cifs: Fix locking in cifs_strict_readv() for-next
authorSteve French <stfrench@microsoft.com>
Mon, 13 May 2024 22:02:05 +0000 (17:02 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 13 May 2024 22:02:05 +0000 (17:02 -0500)
Fix to take the i_rwsem (through the netfs locking wrappers) before taking
cinode->lock_sem.

Fixes: 3ee1a1fc3981 ("cifs: Cut over to using netfslib")
Reported-by: Enzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
1546 files changed:
.mailmap
Documentation/Makefile
Documentation/RCU/whatisRCU.rst
Documentation/admin-guide/cgroup-v2.rst
Documentation/admin-guide/hw-vuln/core-scheduling.rst
Documentation/admin-guide/hw-vuln/srso.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/mm/ksm.rst
Documentation/admin-guide/reporting-regressions.rst
Documentation/arch/m68k/buddha-driver.rst
Documentation/arch/s390/index.rst
Documentation/arch/s390/mm.rst [new file with mode: 0644]
Documentation/arch/s390/vfio-ap.rst
Documentation/arch/sparc/oradax/dax-hv-api.txt
Documentation/arch/x86/xstate.rst
Documentation/atomic_t.txt
Documentation/core-api/dma-api-howto.rst
Documentation/core-api/entry.rst
Documentation/core-api/printk-index.rst
Documentation/core-api/workqueue.rst
Documentation/dev-tools/kcsan.rst
Documentation/devicetree/bindings/access-controllers/access-controllers.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/arm/bcm/brcm,bcm4708.yaml
Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
Documentation/devicetree/bindings/arm/fsl.yaml
Documentation/devicetree/bindings/arm/keystone/ti,sci.yaml
Documentation/devicetree/bindings/arm/qcom.yaml
Documentation/devicetree/bindings/arm/rockchip.yaml
Documentation/devicetree/bindings/arm/sunxi.yaml
Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/google,gs101-clock.yaml
Documentation/devicetree/bindings/crypto/st,stm32-cryp.yaml
Documentation/devicetree/bindings/crypto/st,stm32-hash.yaml
Documentation/devicetree/bindings/display/panel/panel-simple.yaml
Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
Documentation/devicetree/bindings/dma/st,stm32-dma.yaml
Documentation/devicetree/bindings/dma/st,stm32-dmamux.yaml
Documentation/devicetree/bindings/firmware/arm,scmi.yaml
Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt [deleted file]
Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
Documentation/devicetree/bindings/iio/adc/st,stm32-adc.yaml
Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
Documentation/devicetree/bindings/iio/dac/st,stm32-dac.yaml
Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml
Documentation/devicetree/bindings/media/cec/st,stm32-cec.yaml
Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml
Documentation/devicetree/bindings/media/st,stm32mp25-video-codec.yaml
Documentation/devicetree/bindings/memory-controllers/samsung,s5pv210-dmc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
Documentation/devicetree/bindings/mfd/st,stm32-timers.yaml
Documentation/devicetree/bindings/mmc/arm,pl18x.yaml
Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
Documentation/devicetree/bindings/net/mediatek,net.yaml
Documentation/devicetree/bindings/net/stm32-dwmac.yaml
Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml
Documentation/devicetree/bindings/pinctrl/renesas,rzg2l-pinctrl.yaml
Documentation/devicetree/bindings/regulator/st,stm32-vrefbuf.yaml
Documentation/devicetree/bindings/rng/st,stm32-rng.yaml
Documentation/devicetree/bindings/serial/st,stm32-uart.yaml
Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml
Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/soc/renesas/renesas.yaml
Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml
Documentation/devicetree/bindings/sound/rt5645.txt
Documentation/devicetree/bindings/sound/st,stm32-i2s.yaml
Documentation/devicetree/bindings/sound/st,stm32-sai.yaml
Documentation/devicetree/bindings/sound/st,stm32-spdifrx.yaml
Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml
Documentation/devicetree/bindings/spi/st,stm32-spi.yaml
Documentation/devicetree/bindings/tpm/tcg,tpm-tis-i2c.yaml
Documentation/devicetree/bindings/usb/dwc2.yaml
Documentation/devicetree/bindings/usb/fsl,usbmisc.yaml
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/doc-guide/parse-headers.rst
Documentation/driver-api/eisa.rst
Documentation/driver-api/mtd/nand_ecc.rst
Documentation/driver-api/scsi.rst
Documentation/driver-api/usb/usb.rst
Documentation/driver-api/wbrf.rst
Documentation/filesystems/directory-locking.rst
Documentation/filesystems/porting.rst
Documentation/index.rst
Documentation/litmus-tests/README
Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus [new file with mode: 0644]
Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus [new file with mode: 0644]
Documentation/mm/slub.rst
Documentation/netlink/specs/rt_link.yaml
Documentation/process/handling-regressions.rst
Documentation/process/stable-kernel-rules.rst
Documentation/rust/arch-support.rst
Documentation/security/SCTP.rst
Documentation/security/keys/trusted-encrypted.rst
Documentation/security/snp-tdx-threat-model.rst
Documentation/security/tpm/index.rst
Documentation/security/tpm/tpm-security.rst [new file with mode: 0644]
Documentation/security/tpm/tpm_tis.rst [new file with mode: 0644]
Documentation/sphinx/kernel_include.py
Documentation/sphinx/kerneldoc-preamble.sty
Documentation/tee/index.rst
Documentation/tee/ts-tee.rst [new file with mode: 0644]
Documentation/timers/no_hz.rst
Documentation/trace/fprobetrace.rst
Documentation/trace/ftrace.rst
Documentation/trace/kprobes.rst
Documentation/trace/kprobetrace.rst
Documentation/trace/tracepoints.rst
Documentation/translations/it_IT/doc-guide/kernel-doc.rst
Documentation/translations/it_IT/index.rst
Documentation/translations/it_IT/process/2.Process.rst
Documentation/translations/it_IT/process/4.Coding.rst
Documentation/translations/it_IT/process/7.AdvancedTopics.rst
Documentation/translations/it_IT/process/changes.rst
Documentation/translations/it_IT/process/coding-style.rst
Documentation/translations/it_IT/process/deprecated.rst
Documentation/translations/it_IT/process/howto.rst
Documentation/translations/it_IT/process/index.rst
Documentation/translations/it_IT/process/security-bugs.rst [moved from Documentation/translations/it_IT/admin-guide/security-bugs.rst with 100% similarity]
Documentation/translations/it_IT/process/stable-kernel-rules.rst
Documentation/translations/it_IT/process/submitting-patches.rst
Documentation/translations/ja_JP/process/howto.rst
Documentation/translations/sp_SP/index.rst
Documentation/translations/sp_SP/memory-barriers.txt
Documentation/translations/sp_SP/process/1.Intro.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/2.Process.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/3.Early-stage.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/4.Coding.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/5.Posting.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/6.Followthrough.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/7.AdvancedTopics.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/8.Conclusion.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/code-of-conduct.rst
Documentation/translations/sp_SP/process/coding-style.rst
Documentation/translations/sp_SP/process/development-process.rst [new file with mode: 0644]
Documentation/translations/sp_SP/process/email-clients.rst
Documentation/translations/sp_SP/process/howto.rst
Documentation/translations/sp_SP/process/index.rst
Documentation/translations/sp_SP/process/kernel-docs.rst
Documentation/translations/sp_SP/process/kernel-enforcement-statement.rst
Documentation/translations/sp_SP/process/magic-number.rst
Documentation/translations/sp_SP/process/programming-language.rst
Documentation/translations/sp_SP/process/submitting-patches.rst
Documentation/translations/zh_CN/core-api/workqueue.rst
Documentation/translations/zh_CN/dev-tools/index.rst
Documentation/translations/zh_CN/dev-tools/kcov.rst [new file with mode: 0644]
Documentation/translations/zh_CN/dev-tools/kmemleak.rst [new file with mode: 0644]
Documentation/translations/zh_CN/dev-tools/ubsan.rst [new file with mode: 0644]
Documentation/translations/zh_CN/index.rst
Documentation/translations/zh_CN/process/cve.rst [new file with mode: 0644]
Documentation/translations/zh_CN/process/index.rst
Documentation/translations/zh_CN/process/submitting-patches.rst
Documentation/translations/zh_CN/rust/arch-support.rst
Documentation/translations/zh_CN/rust/coding-guidelines.rst
Documentation/translations/zh_CN/rust/general-information.rst
Documentation/translations/zh_CN/rust/quick-start.rst
Documentation/translations/zh_TW/process/submit-checklist.rst
Documentation/translations/zh_TW/process/submitting-patches.rst
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/Makefile
arch/alpha/include/asm/core_apecs.h [deleted file]
arch/alpha/include/asm/core_lca.h [deleted file]
arch/alpha/include/asm/core_t2.h
arch/alpha/include/asm/dma-mapping.h
arch/alpha/include/asm/dma.h
arch/alpha/include/asm/elf.h
arch/alpha/include/asm/io.h
arch/alpha/include/asm/irq.h
arch/alpha/include/asm/jensen.h [deleted file]
arch/alpha/include/asm/machvec.h
arch/alpha/include/asm/mmu_context.h
arch/alpha/include/asm/special_insns.h
arch/alpha/include/asm/tlbflush.h
arch/alpha/include/asm/uaccess.h
arch/alpha/include/asm/vga.h
arch/alpha/include/uapi/asm/compiler.h
arch/alpha/kernel/Makefile
arch/alpha/kernel/asm-offsets.c
arch/alpha/kernel/bugs.c
arch/alpha/kernel/console.c
arch/alpha/kernel/core_apecs.c [deleted file]
arch/alpha/kernel/core_cia.c
arch/alpha/kernel/core_irongate.c
arch/alpha/kernel/core_lca.c [deleted file]
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/core_t2.c
arch/alpha/kernel/core_wildfire.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/io.c
arch/alpha/kernel/irq.c
arch/alpha/kernel/irq_i8259.c
arch/alpha/kernel/machvec_impl.h
arch/alpha/kernel/pci-noop.c [deleted file]
arch/alpha/kernel/pci_impl.h
arch/alpha/kernel/perf_event.c
arch/alpha/kernel/proto.h
arch/alpha/kernel/setup.c
arch/alpha/kernel/smc37c669.c
arch/alpha/kernel/smc37c93x.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/srmcons.c
arch/alpha/kernel/sys_cabriolet.c
arch/alpha/kernel/sys_eb64p.c [deleted file]
arch/alpha/kernel/sys_jensen.c [deleted file]
arch/alpha/kernel/sys_mikasa.c
arch/alpha/kernel/sys_nautilus.c
arch/alpha/kernel/sys_noritake.c
arch/alpha/kernel/sys_sable.c
arch/alpha/kernel/sys_sio.c [deleted file]
arch/alpha/kernel/syscalls/syscall.tbl
arch/alpha/kernel/traps.c
arch/alpha/lib/Makefile
arch/alpha/lib/checksum.c
arch/alpha/lib/fpreg.c
arch/alpha/lib/memcpy.c
arch/alpha/lib/stycpy.S [new file with mode: 0644]
arch/alpha/lib/styncpy.S [new file with mode: 0644]
arch/alpha/math-emu/math.c
arch/alpha/mm/init.c
arch/arm/boot/dts/allwinner/Makefile
arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts [new file with mode: 0644]
arch/arm/boot/dts/allwinner/sun5i-a13.dtsi
arch/arm/boot/dts/allwinner/sun5i-gr8-chip-pro.dts
arch/arm/boot/dts/allwinner/sun5i-r8-chip.dts
arch/arm/boot/dts/allwinner/sun6i-a31-hummingbird.dts
arch/arm/boot/dts/allwinner/sun6i-a31.dtsi
arch/arm/boot/dts/allwinner/sun6i-a31s-sinovoip-bpi-m2.dts
arch/arm/boot/dts/allwinner/sun7i-a20-bananapi-m1-plus.dts
arch/arm/boot/dts/allwinner/sun7i-a20-cubietruck.dts
arch/arm/boot/dts/allwinner/sun7i-a20-hummingbird.dts
arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som-evb-emmc.dts
arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb-emmc.dts
arch/arm/boot/dts/allwinner/sun7i-a20-olimex-som204-evb.dts
arch/arm/boot/dts/allwinner/sun7i-a20-olinuxino-lime2.dts
arch/arm/boot/dts/allwinner/sun7i-a20-wits-pro-a20-dkt.dts
arch/arm/boot/dts/allwinner/sun7i-a20.dtsi
arch/arm/boot/dts/allwinner/sun8i-a23-a33.dtsi
arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2407pxe03.dts
arch/arm/boot/dts/allwinner/sun8i-a23-polaroid-mid2809pxe04.dts
arch/arm/boot/dts/allwinner/sun8i-a33-ga10h-v1.1.dts
arch/arm/boot/dts/allwinner/sun8i-a33-inet-d978-rev2.dts
arch/arm/boot/dts/allwinner/sun8i-a33.dtsi
arch/arm/boot/dts/allwinner/sun8i-a83t-bananapi-m3.dts
arch/arm/boot/dts/allwinner/sun8i-a83t-cubietruck-plus.dts
arch/arm/boot/dts/allwinner/sun8i-a83t-tbs-a711.dts
arch/arm/boot/dts/allwinner/sun8i-a83t.dtsi
arch/arm/boot/dts/allwinner/sun8i-h2-plus-bananapi-m2-zero.dts
arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-r1.dts
arch/arm/boot/dts/allwinner/sun8i-h2-plus-orangepi-zero.dts
arch/arm/boot/dts/allwinner/sun8i-h3-beelink-x2.dts
arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-duo2.dts
arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-m1-plus.dts
arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-neo-air.dts
arch/arm/boot/dts/allwinner/sun8i-h3-nanopi-r1.dts
arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-2.dts
arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-lite.dts
arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-pc-plus.dts
arch/arm/boot/dts/allwinner/sun8i-h3-orangepi-zero-plus2.dts
arch/arm/boot/dts/allwinner/sun8i-q8-common.dtsi
arch/arm/boot/dts/allwinner/sun8i-r16-bananapi-m2m.dts
arch/arm/boot/dts/allwinner/sun8i-r16-parrot.dts
arch/arm/boot/dts/allwinner/sun8i-r40-bananapi-m2-ultra.dts
arch/arm/boot/dts/allwinner/sun8i-r40-oka40i-c.dts
arch/arm/boot/dts/allwinner/sun8i-s3-pinecube.dts
arch/arm/boot/dts/allwinner/sun8i-v3s.dtsi
arch/arm/boot/dts/allwinner/sun8i-v40-bananapi-m2-berry.dts
arch/arm/boot/dts/allwinner/sun9i-a80.dtsi
arch/arm/boot/dts/allwinner/sunxi-bananapi-m2-plus.dtsi
arch/arm/boot/dts/allwinner/sunxi-h3-h5-emlid-neutis.dtsi
arch/arm/boot/dts/allwinner/sunxi-h3-h5.dtsi
arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-romed8hm3.dts
arch/arm/boot/dts/aspeed/aspeed-bmc-delta-ahe50dc.dts
arch/arm/boot/dts/broadcom/Makefile
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts
arch/arm/boot/dts/broadcom/bcm2711-rpi-400.dts
arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dts
arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi
arch/arm/boot/dts/broadcom/bcm2711.dtsi
arch/arm/boot/dts/broadcom/bcm2835-rpi-common.dtsi
arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi
arch/arm/boot/dts/broadcom/bcm283x.dtsi
arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts [new file with mode: 0644]
arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dts
arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac3100.dtsi
arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts [new file with mode: 0644]
arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac88u.dts
arch/arm/boot/dts/nvidia/tegra20-colibri.dtsi
arch/arm/boot/dts/nvidia/tegra20-paz00.dts
arch/arm/boot/dts/nxp/imx/Makefile
arch/arm/boot/dts/nxp/imx/e60k02.dtsi
arch/arm/boot/dts/nxp/imx/e70k02.dtsi
arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-som.dtsi
arch/arm/boot/dts/nxp/imx/imx51-ts4800.dts
arch/arm/boot/dts/nxp/imx/imx53-kp-ddc.dts
arch/arm/boot/dts/nxp/imx/imx53-kp.dtsi
arch/arm/boot/dts/nxp/imx/imx53-m53evk.dts
arch/arm/boot/dts/nxp/imx/imx53-mba53.dts
arch/arm/boot/dts/nxp/imx/imx53-ppd.dts
arch/arm/boot/dts/nxp/imx/imx53-tqma53.dtsi
arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_4.dts
arch/arm/boot/dts/nxp/imx/imx6dl-aristainetos_7.dts
arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts
arch/arm/boot/dts/nxp/imx/imx6q-ba16.dtsi
arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts
arch/arm/boot/dts/nxp/imx/imx6q-kp.dtsi
arch/arm/boot/dts/nxp/imx/imx6q-novena.dts
arch/arm/boot/dts/nxp/imx/imx6q-pistachio.dts
arch/arm/boot/dts/nxp/imx/imx6q-prti6q.dts
arch/arm/boot/dts/nxp/imx/imx6q-var-dt6customboard.dts
arch/arm/boot/dts/nxp/imx/imx6qdl-apf6dev.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-aristainetos2.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-cubox-i.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw52xx.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw53xx.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw54xx.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw5903.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-gw5904.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-icore.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-mba6.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-nit6xlite.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_max.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6_som2.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-nitrogen6x.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-phytec-mira.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-sabreauto.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-sabrelite.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-sabresd.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-savageboard.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl-udoo.dtsi
arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
arch/arm/boot/dts/nxp/imx/imx6sl-evk.dts
arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts
arch/arm/boot/dts/nxp/imx/imx6sll.dtsi
arch/arm/boot/dts/nxp/imx/imx6sx-nitrogen6sx.dts
arch/arm/boot/dts/nxp/imx/imx6sx-sdb.dtsi
arch/arm/boot/dts/nxp/imx/imx6sx-softing-vining-2000.dts
arch/arm/boot/dts/nxp/imx/imx6sx.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul-ccimx6ulsbcpro.dts
arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
arch/arm/boot/dts/nxp/imx/imx6ul-imx6ull-opos6uldev.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul-isiot.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-43.dts
arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi
arch/arm/boot/dts/nxp/imx/imx6ul-pico.dtsi
arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts [new file with mode: 0644]
arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts [new file with mode: 0644]
arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi [new file with mode: 0644]
arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi [new file with mode: 0644]
arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-master.dts
arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slave.dts
arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-slavext.dts
arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts [new file with mode: 0644]
arch/arm/boot/dts/nxp/imx/imx7s.dtsi
arch/arm/boot/dts/qcom/Makefile
arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts [new file with mode: 0644]
arch/arm/boot/dts/qcom/qcom-apq8064.dtsi
arch/arm/boot/dts/qcom/qcom-apq8084.dtsi
arch/arm/boot/dts/qcom/qcom-ipq4019.dtsi
arch/arm/boot/dts/qcom/qcom-ipq8064.dtsi
arch/arm/boot/dts/qcom/qcom-msm8916-smp.dtsi
arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts
arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts [new file with mode: 0644]
arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts
arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts [new file with mode: 0644]
arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
arch/arm/boot/dts/renesas/r7s72100.dtsi
arch/arm/boot/dts/renesas/r8a73a4.dtsi
arch/arm/boot/dts/renesas/r8a7742.dtsi
arch/arm/boot/dts/renesas/r8a7743.dtsi
arch/arm/boot/dts/renesas/r8a7744.dtsi
arch/arm/boot/dts/renesas/r8a7745.dtsi
arch/arm/boot/dts/renesas/r8a77470.dtsi
arch/arm/boot/dts/renesas/r8a7790.dtsi
arch/arm/boot/dts/renesas/r8a7791.dtsi
arch/arm/boot/dts/renesas/r8a7792.dtsi
arch/arm/boot/dts/renesas/r8a7793.dtsi
arch/arm/boot/dts/renesas/r8a7794.dtsi
arch/arm/boot/dts/renesas/r9a06g032.dtsi
arch/arm/boot/dts/samsung/exynos3250.dtsi
arch/arm/boot/dts/samsung/exynos4.dtsi
arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi
arch/arm/boot/dts/samsung/exynos4412-origen.dts
arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
arch/arm/boot/dts/samsung/exynos5250.dtsi
arch/arm/boot/dts/samsung/exynos5420.dtsi
arch/arm/boot/dts/samsung/exynos5800-peach-pi.dts
arch/arm/boot/dts/samsung/s5pv210.dtsi
arch/arm/boot/dts/st/stm32f746.dtsi
arch/arm/boot/dts/st/stm32f769.dtsi
arch/arm/boot/dts/st/stm32mp13-pinctrl.dtsi
arch/arm/boot/dts/st/stm32mp131.dtsi
arch/arm/boot/dts/st/stm32mp133.dtsi
arch/arm/boot/dts/st/stm32mp135.dtsi
arch/arm/boot/dts/st/stm32mp135f-dk.dts
arch/arm/boot/dts/st/stm32mp13xc.dtsi
arch/arm/boot/dts/st/stm32mp13xf.dtsi
arch/arm/boot/dts/st/stm32mp151.dtsi
arch/arm/boot/dts/st/stm32mp153.dtsi
arch/arm/boot/dts/st/stm32mp157c-ed1.dts
arch/arm/boot/dts/st/stm32mp15xc.dtsi
arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
arch/arm/boot/dts/ti/omap/am33xx.dtsi
arch/arm/boot/dts/ti/omap/am4372.dtsi
arch/arm/boot/dts/ti/omap/dra76x.dtsi
arch/arm/boot/dts/ti/omap/dra7xx-clocks.dtsi
arch/arm/boot/dts/ti/omap/omap3-n900.dts
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/kernel/sleep.S
arch/arm/mach-imx/mmdc.c
arch/arm/mach-orion5x/board-d2net.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/net2big-setup.c
arch/arm/mach-orion5x/ts409-setup.c
arch/arm/mach-stm32/Kconfig
arch/arm/net/bpf_jit_32.c
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/actions/s700-cubieboard7.dts
arch/arm64/boot/dts/allwinner/Makefile
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.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-pinebook.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.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-r1s-h5.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-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.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h618-transpeed-8k618-t.dts
arch/arm64/boot/dts/allwinner/sun50i-h64-remix-mini-pc.dts
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts [new file with mode: 0644]
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/amazon/alpine-v2.dtsi
arch/arm64/boot/dts/amazon/alpine-v3.dtsi
arch/arm64/boot/dts/amd/elba-16core.dtsi
arch/arm64/boot/dts/amd/elba-asic-common.dtsi
arch/arm64/boot/dts/amd/elba-asic.dts
arch/arm64/boot/dts/amd/elba-flash-parts.dtsi
arch/arm64/boot/dts/amd/elba.dtsi
arch/arm64/boot/dts/apm/apm-merlin.dts
arch/arm64/boot/dts/apm/apm-mustang.dts
arch/arm64/boot/dts/apm/apm-shadowcat.dtsi
arch/arm64/boot/dts/apm/apm-storm.dtsi
arch/arm64/boot/dts/arm/juno-base.dtsi
arch/arm64/boot/dts/arm/juno-scmi.dtsi
arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
arch/arm64/boot/dts/broadcom/bcmbca/bcm94908.dts
arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts
arch/arm64/boot/dts/broadcom/northstar2/ns2-xmc.dts
arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
arch/arm64/boot/dts/cavium/thunder2-99xx.dts
arch/arm64/boot/dts/cavium/thunder2-99xx.dtsi
arch/arm64/boot/dts/exynos/exynos5433.dtsi
arch/arm64/boot/dts/exynos/exynos850.dtsi
arch/arm64/boot/dts/exynos/exynosautov9.dtsi
arch/arm64/boot/dts/exynos/google/gs101-oriole.dts
arch/arm64/boot/dts/exynos/google/gs101.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3-ads2.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
arch/arm64/boot/dts/freescale/fsl-lx2162a-sr-som.dtsi
arch/arm64/boot/dts/freescale/imx8-ss-audio.dtsi
arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8-ss-img.dtsi
arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dx.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
arch/arm64/boot/dts/freescale/imx8dxl.dtsi
arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
arch/arm64/boot/dts/freescale/imx8mm-var-som-symphony.dts
arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
arch/arm64/boot/dts/freescale/imx8mm-verdin-yavia.dtsi
arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8mn-ddr3l-evk.dts
arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
arch/arm64/boot/dts/freescale/imx8mn-evk.dts
arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
arch/arm64/boot/dts/freescale/imx8mn-var-som-symphony.dts
arch/arm64/boot/dts/freescale/imx8mn.dtsi
arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk3.dts
arch/arm64/boot/dts/freescale/imx8mp-evk.dts
arch/arm64/boot/dts/freescale/imx8mp-msc-sm2s.dtsi
arch/arm64/boot/dts/freescale/imx8mp-navqp.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mp-tqma8mpql-mba8mpxl.dts
arch/arm64/boot/dts/freescale/imx8mp-venice-gw71xx.dtsi
arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx-imx219.dtso
arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts
arch/arm64/boot/dts/freescale/imx8mp-verdin-dahlia.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin-dev.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin-mallow.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi
arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
arch/arm64/boot/dts/freescale/imx8mp.dtsi
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/freescale/imx8qm-mek.dts
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
arch/arm64/boot/dts/freescale/imx8qxp.dtsi
arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
arch/arm64/boot/dts/freescale/imx8ulp.dtsi
arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
arch/arm64/boot/dts/freescale/imx93.dtsi
arch/arm64/boot/dts/freescale/mba8mx.dtsi
arch/arm64/boot/dts/freescale/s32g2.dtsi
arch/arm64/boot/dts/freescale/s32g274a-evb.dts
arch/arm64/boot/dts/freescale/s32g274a-rdb2.dts
arch/arm64/boot/dts/freescale/s32g3.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts [new file with mode: 0644]
arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
arch/arm64/boot/dts/hisilicon/hi6220.dtsi
arch/arm64/boot/dts/hisilicon/hip05-d02.dts
arch/arm64/boot/dts/hisilicon/hip05.dtsi
arch/arm64/boot/dts/hisilicon/hip06.dtsi
arch/arm64/boot/dts/hisilicon/hip07.dtsi
arch/arm64/boot/dts/intel/keembay-soc.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/lg/lg1312-ref.dts
arch/arm64/boot/dts/lg/lg1313-ref.dts
arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi
arch/arm64/boot/dts/marvell/armada-3720-eDPU.dts
arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts
arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/marvell/armada-ap80x.dtsi
arch/arm64/boot/dts/marvell/cn9130-crb.dtsi
arch/arm64/boot/dts/marvell/cn9130-db.dtsi
arch/arm64/boot/dts/marvell/cn9131-db.dtsi
arch/arm64/boot/dts/marvell/cn9132-db.dtsi
arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
arch/arm64/boot/dts/mediatek/mt8516.dtsi
arch/arm64/boot/dts/microchip/sparx5.dtsi
arch/arm64/boot/dts/microchip/sparx5_pcb134_board.dtsi
arch/arm64/boot/dts/microchip/sparx5_pcb135_board.dtsi
arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
arch/arm64/boot/dts/nvidia/tegra132.dtsi
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
arch/arm64/boot/dts/nvidia/tegra210.dtsi
arch/arm64/boot/dts/nvidia/tegra234.dtsi
arch/arm64/boot/dts/qcom/Makefile
arch/arm64/boot/dts/qcom/apq8016-sbc.dts
arch/arm64/boot/dts/qcom/ipq6018.dtsi
arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
arch/arm64/boot/dts/qcom/ipq8074.dtsi
arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
arch/arm64/boot/dts/qcom/msm8916-mtp.dts
arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
arch/arm64/boot/dts/qcom/msm8916-samsung-e2015-common.dtsi
arch/arm64/boot/dts/qcom/msm8916-samsung-fortuna-common.dtsi
arch/arm64/boot/dts/qcom/msm8916-samsung-rossa-common.dtsi
arch/arm64/boot/dts/qcom/msm8939-samsung-a7.dts
arch/arm64/boot/dts/qcom/msm8953.dtsi
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998-sony-xperia-yoshino.dtsi
arch/arm64/boot/dts/qcom/msm8998.dtsi
arch/arm64/boot/dts/qcom/pm6150.dtsi
arch/arm64/boot/dts/qcom/pm6150l.dtsi
arch/arm64/boot/dts/qcom/qcm2290.dtsi
arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
arch/arm64/boot/dts/qcom/qcm6490-idp.dts
arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
arch/arm64/boot/dts/qcom/qdu1000.dtsi
arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
arch/arm64/boot/dts/qcom/sa8155p-adp.dts
arch/arm64/boot/dts/qcom/sa8775p.dtsi
arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
arch/arm64/boot/dts/qcom/sc7180.dtsi
arch/arm64/boot/dts/qcom/sc7280.dtsi
arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
arch/arm64/boot/dts/qcom/sc8180x.dtsi
arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
arch/arm64/boot/dts/qcom/sc8280xp.dtsi
arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi
arch/arm64/boot/dts/qcom/sdm632-fairphone-fp3.dts
arch/arm64/boot/dts/qcom/sdm670-google-sargo.dts
arch/arm64/boot/dts/qcom/sdm845-db845c.dts
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sdx75.dtsi
arch/arm64/boot/dts/qcom/sm6350.dtsi
arch/arm64/boot/dts/qcom/sm8150-hdk.dts
arch/arm64/boot/dts/qcom/sm8150.dtsi
arch/arm64/boot/dts/qcom/sm8250-xiaomi-elish-common.dtsi
arch/arm64/boot/dts/qcom/sm8250.dtsi
arch/arm64/boot/dts/qcom/sm8350-hdk.dts
arch/arm64/boot/dts/qcom/sm8350.dtsi
arch/arm64/boot/dts/qcom/sm8450-hdk.dts
arch/arm64/boot/dts/qcom/sm8450-qrd.dts
arch/arm64/boot/dts/qcom/sm8450.dtsi
arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sm8550.dtsi
arch/arm64/boot/dts/qcom/sm8650-mtp.dts
arch/arm64/boot/dts/qcom/sm8650-qrd.dts
arch/arm64/boot/dts/qcom/sm8650.dtsi
arch/arm64/boot/dts/qcom/x1e80100-crd.dts
arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
arch/arm64/boot/dts/qcom/x1e80100.dtsi
arch/arm64/boot/dts/realtek/rtd129x.dtsi
arch/arm64/boot/dts/realtek/rtd139x.dtsi
arch/arm64/boot/dts/realtek/rtd16xx.dtsi
arch/arm64/boot/dts/renesas/Makefile
arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
arch/arm64/boot/dts/renesas/r8a779h0-gray-hawk-single.dts
arch/arm64/boot/dts/renesas/r8a779h0.dtsi
arch/arm64/boot/dts/renesas/r9a07g043.dtsi
arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
arch/arm64/boot/dts/renesas/rzg2ul-smarc.dtsi
arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
arch/arm64/boot/dts/rockchip/Makefile
arch/arm64/boot/dts/rockchip/rk3308.dtsi
arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi
arch/arm64/boot/dts/rockchip/rk3368-orion-r68-meta.dts
arch/arm64/boot/dts/rockchip/rk3368-r88.dts
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
arch/arm64/boot/dts/rockchip/rk3399-rock-4c-plus.dts
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dtsi
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353ps.dts
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353vs.dts
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rgb30.dts
arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dts
arch/arm64/boot/dts/rockchip/rk3566-powkiddy-rk2023.dtsi
arch/arm64/boot/dts/rockchip/rk3566-powkiddy-x55.dts
arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3566-soquartz-blade.dts
arch/arm64/boot/dts/rockchip/rk3566-soquartz-cm4.dts
arch/arm64/boot/dts/rockchip/rk3566-soquartz-model-a.dts
arch/arm64/boot/dts/rockchip/rk3566-soquartz.dtsi
arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk356x.dtsi
arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-common.dtsi
arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
arch/arm64/boot/dts/rockchip/rk3588-evb1-v10.dts
arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3588-quartzpro64.dts
arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts
arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
arch/arm64/boot/dts/rockchip/rk3588.dtsi
arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2.dts
arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
arch/arm64/boot/dts/rockchip/rk3588s.dtsi
arch/arm64/boot/dts/socionext/uniphier-ld11-global.dts
arch/arm64/boot/dts/socionext/uniphier-ld20-global.dts
arch/arm64/boot/dts/sprd/sc9860.dtsi
arch/arm64/boot/dts/sprd/sc9863a.dtsi
arch/arm64/boot/dts/sprd/sharkl3.dtsi
arch/arm64/boot/dts/sprd/sp9860g-1h10.dts
arch/arm64/boot/dts/sprd/whale2.dtsi
arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
arch/arm64/boot/dts/st/stm32mp251.dtsi
arch/arm64/boot/dts/st/stm32mp253.dtsi
arch/arm64/boot/dts/st/stm32mp255.dtsi
arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
arch/arm64/boot/dts/synaptics/berlin4ct.dtsi
arch/arm64/boot/dts/tesla/fsd.dtsi
arch/arm64/boot/dts/ti/Makefile
arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
arch/arm64/boot/dts/ti/k3-am62-main.dtsi
arch/arm64/boot/dts/ti/k3-am62-verdin-dahlia.dtsi
arch/arm64/boot/dts/ti/k3-am62-verdin-dev.dtsi
arch/arm64/boot/dts/ti/k3-am62-verdin-mallow.dtsi
arch/arm64/boot/dts/ti/k3-am62-verdin-yavia.dtsi
arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
arch/arm64/boot/dts/ti/k3-am62-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
arch/arm64/boot/dts/ti/k3-am625-phyboard-lyra-rdk.dts
arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
arch/arm64/boot/dts/ti/k3-am62a-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
arch/arm64/boot/dts/ti/k3-am642-evm.dts
arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-rdk.dts
arch/arm64/boot/dts/ti/k3-am642-sk.dts
arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
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-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-am69-sk.dts
arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
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-j721s2-main.dtsi
arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-j721s2.dtsi
arch/arm64/boot/dts/ti/k3-j722s-evm.dts
arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-j784s4.dtsi
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
arch/arm64/configs/defconfig
arch/arm64/kvm/vgic/vgic-kvm-device.c
arch/arm64/net/bpf_jit_comp.c
arch/csky/Kconfig
arch/csky/include/asm/cmpxchg.h
arch/parisc/include/asm/cmpxchg.h
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/lib/bitops.c
arch/powerpc/include/asm/plpks.h
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/plpks.c
arch/riscv/Kconfig.errata
arch/riscv/Kconfig.socs
arch/riscv/Makefile
arch/riscv/boot/dts/renesas/r9a07g043f.dtsi
arch/riscv/boot/dts/renesas/rzfive-smarc-som.dtsi
arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
arch/riscv/boot/dts/sophgo/cv1800b.dtsi
arch/riscv/boot/dts/sophgo/cv1812h.dtsi
arch/riscv/boot/dts/sophgo/cv18xx.dtsi
arch/riscv/configs/defconfig
arch/riscv/configs/nommu_k210_defconfig
arch/riscv/configs/nommu_k210_sdcard_defconfig
arch/riscv/configs/nommu_virt_defconfig
arch/riscv/errata/thead/errata.c
arch/riscv/include/asm/errata_list.h
arch/riscv/include/asm/page.h
arch/riscv/include/asm/pgtable.h
arch/riscv/include/uapi/asm/hwprobe.h
arch/riscv/mm/init.c
arch/riscv/net/bpf_jit_comp64.c
arch/s390/Kconfig
arch/s390/Makefile
arch/s390/boot/Makefile
arch/s390/boot/boot.h
arch/s390/boot/decompressor.c
arch/s390/boot/decompressor.h
arch/s390/boot/kaslr.c
arch/s390/boot/pgm_check_info.c
arch/s390/boot/startup.c
arch/s390/boot/vmem.c
arch/s390/boot/vmlinux.lds.S
arch/s390/crypto/paes_s390.c
arch/s390/include/asm/ap.h
arch/s390/include/asm/asm-prototypes.h
arch/s390/include/asm/chsc.h
arch/s390/include/asm/dwarf.h
arch/s390/include/asm/extmem.h
arch/s390/include/asm/ftrace.h
arch/s390/include/asm/gmap.h
arch/s390/include/asm/mmu.h
arch/s390/include/asm/mmu_context.h
arch/s390/include/asm/nospec-branch.h
arch/s390/include/asm/nospec-insn.h
arch/s390/include/asm/os_info.h
arch/s390/include/asm/page.h
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/physmem_info.h
arch/s390/include/asm/setup.h
arch/s390/kernel/Makefile
arch/s390/kernel/crash_dump.c
arch/s390/kernel/ipl.c
arch/s390/kernel/nospec-branch.c
arch/s390/kernel/os_info.c
arch/s390/kernel/perf_cpum_cf.c
arch/s390/kernel/perf_cpum_cf_events.c
arch/s390/kernel/setup.c
arch/s390/kernel/stacktrace.c
arch/s390/kernel/uv.c
arch/s390/kernel/vdso64/vdso_user_wrapper.S
arch/s390/kernel/vmcore_info.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/kvm/kvm-s390.c
arch/s390/kvm/vsie.c
arch/s390/lib/Makefile
arch/s390/lib/expoline.S [moved from arch/s390/lib/expoline/expoline.S with 100% similarity]
arch/s390/lib/expoline/Makefile [deleted file]
arch/s390/mm/gmap.c
arch/s390/mm/hugetlbpage.c
arch/s390/mm/vmem.c
arch/s390/pci/pci_sysfs.c
arch/s390/tools/relocs.c
arch/sparc/include/asm/cmpxchg_32.h
arch/sparc/lib/atomic32.c
arch/x86/Kconfig
arch/x86/entry/vsyscall/vsyscall_64.c
arch/x86/include/asm/coco.h
arch/x86/include/asm/e820/api.h
arch/x86/include/asm/pgtable_types.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/sev.h
arch/x86/kernel/amd_nb.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/topology_amd.c
arch/x86/kernel/e820.c
arch/x86/kernel/process_64.c
arch/x86/kernel/sev-shared.c
arch/x86/mm/fault.c
arch/x86/mm/mem_encrypt.c
arch/x86/net/bpf_jit_comp.c
arch/x86/virt/svm/sev.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/smp_pv.c
arch/xtensa/include/asm/cacheflush.h
arch/xtensa/include/asm/processor.h
arch/xtensa/include/asm/ptrace.h
arch/xtensa/kernel/process.c
arch/xtensa/kernel/stacktrace.c
arch/xtensa/platforms/iss/console.c
block/bdev.c
block/blk-settings.c
block/fops.c
drivers/auxdisplay/Kconfig
drivers/auxdisplay/Makefile
drivers/auxdisplay/charlcd.c
drivers/auxdisplay/seg-led-gpio.c
drivers/base/regmap/regmap.c
drivers/block/ublk_drv.c
drivers/bluetooth/btqca.c
drivers/bluetooth/btqca.h
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/brcmstb_gisb.c
drivers/bus/stm32_etzpc.c [new file with mode: 0644]
drivers/bus/stm32_firewall.c [new file with mode: 0644]
drivers/bus/stm32_firewall.h [new file with mode: 0644]
drivers/bus/stm32_rifsc.c [new file with mode: 0644]
drivers/bus/ti-sysc.c
drivers/cache/sifive_ccache.c
drivers/char/agp/alpha-agp.c
drivers/char/tpm/Kconfig
drivers/char/tpm/Makefile
drivers/char/tpm/eventlog/acpi.c
drivers/char/tpm/tpm-buf.c [new file with mode: 0644]
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm-sysfs.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm2-cmd.c
drivers/char/tpm/tpm2-sessions.c [new file with mode: 0644]
drivers/char/tpm/tpm2-space.c
drivers/char/tpm/tpm_infineon.c
drivers/char/tpm/tpm_tis_core.c
drivers/clk/Kconfig
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/gdsc.c
drivers/clk/samsung/clk-exynos-clkout.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun50i-h6.c
drivers/clk/sunxi-ng/ccu_common.c
drivers/clk/sunxi-ng/ccu_common.h
drivers/crypto/Kconfig
drivers/crypto/mxs-dcp.c
drivers/cxl/core/port.c
drivers/dax/device.c
drivers/edac/synopsys_edac.c
drivers/edac/versal_edac.c
drivers/eisa/Kconfig
drivers/eisa/virtual_root.c
drivers/firewire/nosy.c
drivers/firewire/ohci.c
drivers/firmware/arm_ffa/driver.c
drivers/firmware/arm_scmi/Makefile
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/mailbox.c
drivers/firmware/arm_scmi/notify.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/pinctrl.c [new file with mode: 0644]
drivers/firmware/arm_scmi/protocols.h
drivers/firmware/efi/unaccepted_memory.c
drivers/firmware/microchip/mpfs-auto-update.c
drivers/firmware/qcom/qcom_scm.c
drivers/firmware/raspberrypi.c
drivers/firmware/ti_sci.c
drivers/fpga/dfl-pci.c
drivers/gpio/gpiolib-cdev.c
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_process.c
drivers/gpu/drm/amd/amdkfd/kfd_topology.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/i915/display/intel_audio.c
drivers/gpu/drm/i915/display/intel_bios.c
drivers/gpu/drm/i915/display/intel_vbt_defs.h
drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.c
drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.h
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/imagination/pvr_fw_mips.h
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
drivers/gpu/drm/panel/Kconfig
drivers/gpu/drm/panel/panel-ilitek-ili9341.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/ttm/ttm_tt.c
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
drivers/gpu/drm/xe/xe_guc_ads.c
drivers/gpu/drm/xe/xe_guc_ct.c
drivers/gpu/drm/xe/xe_guc_ct.h
drivers/gpu/drm/xe/xe_guc_ct_types.h
drivers/gpu/drm/xe/xe_vm.c
drivers/hwmon/corsair-cpro.c
drivers/hwmon/pmbus/ucd9000.c
drivers/iio/accel/mxc4005.c
drivers/iio/imu/adis16475.c
drivers/iio/pressure/bmp280-core.c
drivers/iio/pressure/bmp280-spi.c
drivers/iio/pressure/bmp280.h
drivers/infiniband/hw/qib/qib_fs.c
drivers/input/joystick/xpad.c
drivers/input/mouse/amimouse.c
drivers/input/serio/i8042-io.h
drivers/iommu/amd/iommu.c
drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
drivers/irqchip/irq-gic-v3-its.c
drivers/memory/brcmstb_memc.c
drivers/memory/mtk-smi.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/pci-me.c
drivers/misc/mei/pxp/mei_pxp.c
drivers/misc/pvpanic/pvpanic-pci.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/broadcom/genet/bcmgenet.h
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/ethernet/brocade/bna/bnad_debugfs.c
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
drivers/net/ethernet/intel/e1000e/phy.c
drivers/net/ethernet/intel/ice/ice_debugfs.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
drivers/net/ethernet/micrel/ks8851_common.c
drivers/net/ethernet/qlogic/qede/qede_filter.c
drivers/net/phy/marvell-88q2xxx.c
drivers/net/vxlan/vxlan_core.c
drivers/nvme/host/core.c
drivers/nvme/host/multipath.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c
drivers/nvme/host/tcp.c
drivers/nvme/target/auth.c
drivers/nvme/target/configfs.c
drivers/nvme/target/core.c
drivers/nvme/target/nvmet.h
drivers/nvme/target/rdma.c
drivers/nvme/target/tcp.c
drivers/of/property.c
drivers/pci/pcie/aspm.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
drivers/pinctrl/core.c
drivers/pinctrl/devicetree.c
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/intel/pinctrl-intel.h
drivers/pinctrl/mediatek/pinctrl-paris.c
drivers/pinctrl/meson/pinctrl-meson-a1.c
drivers/pinctrl/pinctrl-scmi.c [new file with mode: 0644]
drivers/pinctrl/renesas/pinctrl-rzg2l.c
drivers/platform/x86/intel/speed_select_if/isst_if_common.c
drivers/power/supply/mt6360_charger.c
drivers/power/supply/rt9455_charger.c
drivers/regulator/core.c
drivers/regulator/irq_helpers.c
drivers/regulator/mt6360-regulator.c
drivers/regulator/qcom-refgen-regulator.c
drivers/regulator/rtq2208-regulator.c
drivers/regulator/vqmmc-ipq4019-regulator.c
drivers/reset/Kconfig
drivers/s390/char/Makefile
drivers/s390/char/raw3270.c
drivers/s390/cio/chp.c
drivers/s390/cio/chp.h
drivers/s390/cio/chsc.c
drivers/s390/cio/chsc.h
drivers/s390/cio/cio_inject.c
drivers/s390/cio/css.c
drivers/s390/cio/css.h
drivers/s390/cio/trace.h
drivers/s390/crypto/Makefile
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_queue.c
drivers/s390/crypto/vfio_ap_ops.c
drivers/s390/crypto/vfio_ap_private.h
drivers/s390/crypto/zcrypt_ccamisc.c
drivers/s390/crypto/zcrypt_ep11misc.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/sd.c
drivers/slimbus/qcom-ngd-ctrl.c
drivers/soc/Makefile
drivers/soc/canaan/Kconfig
drivers/soc/hisilicon/Kconfig
drivers/soc/hisilicon/kunpeng_hccs.c
drivers/soc/mediatek/mtk-cmdq-helper.c
drivers/soc/mediatek/mtk-mutex.c
drivers/soc/mediatek/mtk-socinfo.c
drivers/soc/qcom/cmd-db.c
drivers/soc/qcom/icc-bwmon.c
drivers/soc/qcom/pmic_glink.c
drivers/soc/qcom/pmic_pdcharger_ulog.c
drivers/soc/qcom/qcom_stats.c
drivers/soc/qcom/rpm_master_stats.c
drivers/soc/qcom/rpmh-rsc.c
drivers/soc/qcom/socinfo.c
drivers/soc/renesas/Kconfig
drivers/soc/renesas/renesas-soc.c
drivers/soc/tegra/pmc.c
drivers/soc/ti/wkup_m3_ipc.c
drivers/spi/spi-axi-spi-engine.c
drivers/spi/spi-hisi-kunpeng.c
drivers/spi/spi-microchip-core-qspi.c
drivers/spi/spi-stm32.c
drivers/spi/spi.c
drivers/tee/Kconfig
drivers/tee/Makefile
drivers/tee/amdtee/amdtee_private.h
drivers/tee/amdtee/call.c
drivers/tee/amdtee/core.c
drivers/tee/amdtee/shm_pool.c
drivers/tee/optee/call.c
drivers/tee/optee/core.c
drivers/tee/optee/device.c
drivers/tee/optee/ffa_abi.c
drivers/tee/optee/notif.c
drivers/tee/optee/optee_private.h
drivers/tee/optee/rpc.c
drivers/tee/optee/smc_abi.c
drivers/tee/tee_core.c
drivers/tee/tee_private.h
drivers/tee/tee_shm.c
drivers/tee/tee_shm_pool.c
drivers/tee/tstee/Kconfig [new file with mode: 0644]
drivers/tee/tstee/Makefile [new file with mode: 0644]
drivers/tee/tstee/core.c [new file with mode: 0644]
drivers/tee/tstee/tstee_private.h [new file with mode: 0644]
drivers/thermal/thermal_debugfs.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_alpha.c [deleted file]
drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/8250/Makefile
drivers/usb/core/hub.c
drivers/usb/core/port.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c
drivers/usb/dwc3/host.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/uvc_configfs.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/xhci-plat.h
drivers/usb/host/xhci-rzv2m.c
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_pdphy.c
drivers/usb/typec/tcpm/tcpm.c
fs/9p/vfs_addr.c
fs/afs/file.c
fs/afs/internal.h
fs/afs/rotate.c
fs/afs/validation.c
fs/afs/write.c
fs/aio.c
fs/anon_inodes.c
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_background.h
fs/bcachefs/backpointers.c
fs/bcachefs/backpointers.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/bkey_methods.c
fs/bcachefs/btree_key_cache.c
fs/bcachefs/btree_node_scan.c
fs/bcachefs/btree_node_scan_types.h
fs/bcachefs/buckets.c
fs/bcachefs/checksum.c
fs/bcachefs/errcode.h
fs/bcachefs/fs.c
fs/bcachefs/inode.c
fs/bcachefs/io_write.c
fs/bcachefs/journal.c
fs/bcachefs/move.c
fs/bcachefs/quota.c
fs/bcachefs/recovery.c
fs/bcachefs/sb-clean.c
fs/bcachefs/sb-members.c
fs/bcachefs/sb-members.h
fs/bcachefs/super-io.c
fs/bcachefs/super.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ordered-data.c
fs/btrfs/qgroup.c
fs/btrfs/tree-checker.c
fs/btrfs/tree-checker.h
fs/btrfs/volumes.c
fs/cachefiles/io.c
fs/ceph/addr.c
fs/ceph/inode.c
fs/dcache.c
fs/debugfs/inode.c
fs/direct-io.c
fs/ecryptfs/keystore.c
fs/erofs/fscache.c
fs/erofs/internal.h
fs/erofs/super.c
fs/eventpoll.c
fs/exfat/dir.c
fs/exfat/file.c
fs/ext4/file.c
fs/ext4/super.c
fs/f2fs/file.c
fs/fcntl.c
fs/fhandle.c
fs/freevxfs/vxfs_super.c
fs/fs-writeback.c
fs/fuse/passthrough.c
fs/fuse/virtio_fs.c
fs/hugetlbfs/inode.c
fs/iomap/buffered-io.c
fs/jffs2/xattr.c
fs/libfs.c
fs/minix/inode.c
fs/namei.c
fs/netfs/Makefile
fs/netfs/buffered_read.c
fs/netfs/buffered_write.c
fs/netfs/direct_read.c
fs/netfs/direct_write.c
fs/netfs/fscache_io.c
fs/netfs/internal.h
fs/netfs/io.c
fs/netfs/main.c
fs/netfs/misc.c
fs/netfs/objects.c
fs/netfs/output.c [deleted file]
fs/netfs/stats.c
fs/netfs/write_collect.c [new file with mode: 0644]
fs/netfs/write_issue.c [new file with mode: 0644]
fs/nfs/file.c
fs/nfs/fscache.h
fs/nfs/inode.c
fs/nfs/write.c
fs/nfsd/nfs4xdr.c
fs/nilfs2/ioctl.c
fs/openpromfs/inode.c
fs/orangefs/dcache.c
fs/orangefs/namei.c
fs/orangefs/super.c
fs/overlayfs/params.c
fs/proc/fd.c
fs/proc/proc_net.c
fs/proc/task_mmu.c
fs/qnx6/inode.c
fs/read_write.c
fs/seq_file.c
fs/signalfd.c
fs/smb/client/Kconfig
fs/smb/client/cifsfs.c
fs/smb/client/cifsfs.h
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/cifssmb.c
fs/smb/client/file.c
fs/smb/client/fscache.c
fs/smb/client/fscache.h
fs/smb/client/inode.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2pdu.h
fs/smb/client/smb2proto.h
fs/smb/client/trace.h
fs/smb/client/transport.c
fs/smb/common/smb2pdu.h
fs/smb/server/oplock.c
fs/smb/server/smb2pdu.c
fs/smb/server/smb2pdu.h
fs/smb/server/smb_common.c
fs/smb/server/transport_tcp.c
fs/smb/server/vfs_cache.c
fs/smb/server/vfs_cache.h
fs/stat.c
fs/timerfd.c
fs/tracefs/event_inode.c
fs/tracefs/inode.c
fs/tracefs/internal.h
fs/userfaultfd.c
fs/xfs/xfs_file.c
include/crypto/aes.h
include/dt-bindings/arm/qcom,ids.h
include/dt-bindings/clock/google,gs101.h
include/dt-bindings/clock/r8a73a4-clock.h
include/keys/trusted_dcp.h [new file with mode: 0644]
include/keys/trusted_tpm.h
include/linux/anon_inodes.h
include/linux/arm_ffa.h
include/linux/blk_types.h
include/linux/bus/stm32_firewall_device.h [new file with mode: 0644]
include/linux/cmpxchg-emu.h [new file with mode: 0644]
include/linux/compiler_types.h
include/linux/cpu.h
include/linux/dma-fence.h
include/linux/file.h
include/linux/filter.h
include/linux/fs.h
include/linux/fs_parser.h
include/linux/fscache.h
include/linux/hugetlb.h
include/linux/namei.h
include/linux/netfs.h
include/linux/pagemap.h
include/linux/pci_ids.h
include/linux/platform_data/ti-sysc.h
include/linux/rcupdate.h
include/linux/rcupdate_wait.h
include/linux/regmap.h
include/linux/regulator/consumer.h
include/linux/scmi_protocol.h
include/linux/seq_file.h
include/linux/shm.h
include/linux/skbuff.h
include/linux/skmsg.h
include/linux/slab.h
include/linux/soc/mediatek/mtk-cmdq.h
include/linux/srcutiny.h
include/linux/stat.h
include/linux/tee_core.h [new file with mode: 0644]
include/linux/tee_drv.h
include/linux/tpm.h
include/linux/tracefs.h
include/linux/tty.h
include/linux/uio.h
include/net/9p/client.h
include/net/gro.h
include/net/udp.h
include/net/xfrm.h
include/soc/fsl/dcp.h [new file with mode: 0644]
include/soc/qcom/cmd-db.h
include/sound/cs35l56.h
include/sound/emu10k1.h
include/trace/events/netfs.h
include/trace/events/rcu.h
include/trace/events/scmi.h
include/uapi/linux/fcntl.h
include/uapi/linux/stat.h
include/uapi/linux/tee.h
include/uapi/linux/xfrm.h
init/Kconfig
io_uring/io_uring.c
io_uring/rw.c
ipc/shm.c
kernel/bounds.c
kernel/bpf/Kconfig
kernel/bpf/core.c
kernel/bpf/trampoline.c
kernel/bpf/verifier.c
kernel/cpu.c
kernel/dma/swiotlb.c
kernel/kcsan/kcsan_test.c
kernel/rcu/Kconfig
kernel/rcu/rcu.h
kernel/rcu/rcutorture.c
kernel/rcu/srcutiny.c
kernel/rcu/srcutree.c
kernel/rcu/sync.c
kernel/rcu/tasks.h
kernel/rcu/tiny.c
kernel/rcu/tree.c
kernel/rcu/tree.h
kernel/rcu/tree_exp.h
kernel/rcu/tree_plugin.h
kernel/rcu/tree_stall.h
kernel/rcu/update.c
kernel/sched/fair.c
kernel/sched/isolation.c
kernel/softirq.c
kernel/time/timer_migration.c
kernel/trace/Kconfig
kernel/trace/ftrace.c
kernel/trace/trace_events.c
kernel/trace/trace_probe.c
kernel/workqueue.c
lib/Kconfig.debug
lib/Makefile
lib/cmpxchg-emu.c [new file with mode: 0644]
lib/crypto/Kconfig
lib/crypto/Makefile
lib/crypto/aescfb.c [new file with mode: 0644]
lib/dynamic_debug.c
lib/maple_tree.c
lib/scatterlist.c
lib/slub_kunit.c
lib/test_xarray.c
lib/xarray.c
mm/Kconfig
mm/filemap.c
mm/mmap.c
mm/page-writeback.c
mm/page_owner.c
mm/readahead.c
mm/shmem.c
mm/slab.h
mm/slab_common.c
mm/slub.c
mm/userfaultfd.c
mm/vmalloc.c
net/8021q/vlan_core.c
net/9p/Kconfig
net/9p/client.c
net/appletalk/ddp.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bluetooth/msft.c
net/bluetooth/msft.h
net/bluetooth/sco.c
net/bridge/br_forward.c
net/core/filter.c
net/core/gro.c
net/core/net_namespace.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/skmsg.c
net/hsr/hsr_device.c
net/ipv4/af_inet.c
net/ipv4/ip_output.c
net/ipv4/raw.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/xfrm4_input.c
net/ipv6/fib6_rules.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_output.c
net/ipv6/udp.c
net/ipv6/udp_offload.c
net/ipv6/xfrm6_input.c
net/l2tp/l2tp_eth.c
net/mptcp/ctrl.c
net/mptcp/protocol.c
net/nfc/nci/core.c
net/nsh/nsh.c
net/phonet/pn_netlink.c
net/rxrpc/ar-internal.h
net/rxrpc/call_object.c
net/rxrpc/conn_object.c
net/rxrpc/input.c
net/rxrpc/insecure.c
net/rxrpc/rxkad.c
net/rxrpc/txbuf.c
net/smc/smc_ib.c
net/sunrpc/xprtsock.c
net/tipc/msg.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_policy.c
rust/Makefile
rust/kernel/init.rs
rust/kernel/lib.rs
rust/kernel/net/phy.rs
rust/macros/lib.rs
rust/macros/module.rs
scripts/Makefile.build
scripts/check-variable-fonts.sh [new file with mode: 0755]
scripts/kernel-doc
scripts/mod/modpost.c
scripts/sphinx-pre-install
security/keys/gc.c
security/keys/key.c
security/keys/keyctl.c
security/keys/trusted-keys/Kconfig
security/keys/trusted-keys/Makefile
security/keys/trusted-keys/trusted_core.c
security/keys/trusted-keys/trusted_dcp.c [new file with mode: 0644]
security/keys/trusted-keys/trusted_tpm1.c
security/keys/trusted-keys/trusted_tpm2.c
sound/hda/intel-dsp-config.c
sound/hda/intel-sdw-acpi.c
sound/pci/emu10k1/emu10k1.c
sound/pci/emu10k1/emu10k1_main.c
sound/pci/emu10k1/emumixer.c
sound/pci/emu10k1/emuproc.c
sound/pci/emu10k1/io.c
sound/pci/hda/cs35l56_hda.c
sound/pci/hda/patch_realtek.c
sound/soc/amd/yc/acp6x-mach.c
sound/soc/codecs/cs35l41.c
sound/soc/codecs/cs35l56-sdw.c
sound/soc/codecs/cs35l56-shared.c
sound/soc/codecs/cs35l56.c
sound/soc/codecs/da7219-aad.c
sound/soc/codecs/rt5645.c
sound/soc/codecs/rt715-sdca.c
sound/soc/codecs/rt715-sdw.c
sound/soc/codecs/rt722-sdca.c
sound/soc/codecs/rt722-sdca.h
sound/soc/codecs/wsa881x.c
sound/soc/intel/avs/icl.c
sound/soc/intel/avs/topology.c
sound/soc/intel/boards/bytcr_rt5640.c
sound/soc/meson/Kconfig
sound/soc/meson/axg-card.c
sound/soc/meson/axg-fifo.c
sound/soc/meson/axg-tdm-formatter.c
sound/soc/meson/axg-tdm-interface.c
sound/soc/meson/axg-tdm.h
sound/soc/sof/core.c
sound/soc/sof/debug.c
sound/soc/sof/intel/pci-lnl.c
sound/soc/sof/ipc3-pcm.c
sound/soc/sof/ipc4-pcm.c
sound/soc/sof/pcm.c
sound/soc/sof/sof-audio.h
sound/soc/tegra/tegra186_dspk.c
sound/soc/ti/davinci-mcasp.c
tools/perf/arch/riscv/util/header.c
tools/testing/cxl/test/cxl.c
tools/testing/kunit/qemu_configs/riscv.py
tools/testing/radix-tree/linux/kernel.h
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
tools/testing/selftests/core/close_range_test.c
tools/testing/selftests/kselftest_harness.h
tools/testing/selftests/kvm/aarch64/vgic_init.c
tools/testing/selftests/landlock/fs_test.c
tools/testing/selftests/mm/Makefile
tools/testing/selftests/net/test_bridge_neigh_suppress.sh
tools/testing/selftests/pidfd/config
tools/testing/selftests/pidfd/pidfd_setns_test.c
tools/testing/selftests/rcutorture/bin/torture.sh
tools/testing/selftests/rcutorture/configs/rcu/TREE09
tools/testing/selftests/riscv/hwprobe/cbo.c
tools/testing/selftests/riscv/hwprobe/hwprobe.h
tools/testing/selftests/syscall_user_dispatch/sud_test.c
tools/testing/selftests/vDSO/vdso_config.h
tools/testing/selftests/vDSO/vdso_test_getcpu.c
tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
tools/testing/selftests/wireguard/qemu/arch/riscv32.config
tools/testing/selftests/wireguard/qemu/arch/riscv64.config

index 16b704e1d5d3665d178f48992a8e3d03cad57cac..df56e43cb57f554a02fddbc253264a7165fb5879 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -97,6 +97,11 @@ Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@linaro.org>
 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com>
 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com>
 Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com>
+Barry Song <baohua@kernel.org> <21cnbao@gmail.com>
+Barry Song <baohua@kernel.org> <v-songbaohua@oppo.com>
+Barry Song <baohua@kernel.org> <song.bao.hua@hisilicon.com>
+Barry Song <baohua@kernel.org> <Baohua.Song@csr.com>
+Barry Song <baohua@kernel.org> <barry.song@analog.com>
 Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
 Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
 Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com>
@@ -128,6 +133,7 @@ Bryan Tan <bryan-bt.tan@broadcom.com> <bryantan@vmware.com>
 Cai Huoqing <cai.huoqing@linux.dev> <caihuoqing@baidu.com>
 Can Guo <quic_cang@quicinc.com> <cang@codeaurora.org>
 Carl Huang <quic_cjhuang@quicinc.com> <cjhuang@codeaurora.org>
+Carlos Bilbao <carlos.bilbao.osdev@gmail.com> <carlos.bilbao@amd.com>
 Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
 Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
 Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
@@ -304,6 +310,7 @@ Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
 Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
 John Crispin <john@phrozen.org> <blogic@openwrt.org>
 John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
+John Garry <john.g.garry@oracle.com> <john.garry@huawei.com>
 John Keeping <john@keeping.me.uk> <john@metanate.com>
 John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com>
 John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
@@ -461,7 +468,8 @@ Nadia Yvette Chambers <nyc@holomorphy.com> William Lee Irwin III <wli@holomorphy
 Naoya Horiguchi <nao.horiguchi@gmail.com> <n-horiguchi@ah.jp.nec.com>
 Naoya Horiguchi <nao.horiguchi@gmail.com> <naoya.horiguchi@nec.com>
 Nathan Chancellor <nathan@kernel.org> <natechancellor@gmail.com>
-Neeraj Upadhyay <quic_neeraju@quicinc.com> <neeraju@codeaurora.org>
+Neeraj Upadhyay <neeraj.upadhyay@kernel.org> <quic_neeraju@quicinc.com>
+Neeraj Upadhyay <neeraj.upadhyay@kernel.org> <neeraju@codeaurora.org>
 Neil Armstrong <neil.armstrong@linaro.org> <narmstrong@baylibre.com>
 Nguyen Anh Quynh <aquynh@gmail.com>
 Nicholas Piggin <npiggin@gmail.com> <npiggen@suse.de>
@@ -512,6 +520,7 @@ Praveen BP <praveenbp@ti.com>
 Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com> <pradeepc@codeaurora.org>
 Prasad Sodagudi <quic_psodagud@quicinc.com> <psodagud@codeaurora.org>
 Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com>
+Puranjay Mohan <puranjay@kernel.org> <puranjay12@gmail.com>
 Qais Yousef <qyousef@layalina.io> <qais.yousef@imgtec.com>
 Qais Yousef <qyousef@layalina.io> <qais.yousef@arm.com>
 Quentin Monnet <qmo@kernel.org> <quentin.monnet@netronome.com>
index b68f8c816897b460b3c99191f0736b3160e22bfd..a961692baa1220fb560533dfb081a17d34278010 100644 (file)
@@ -28,6 +28,10 @@ BUILDDIR      = $(obj)/output
 PDFLATEX      = xelatex
 LATEXOPTS     = -interaction=batchmode -no-shell-escape
 
+# For denylisting "variable font" files
+# Can be overridden by setting as an env variable
+FONTS_CONF_DENY_VF ?= $(HOME)/deny-vf
+
 ifeq ($(findstring 1, $(KBUILD_VERBOSE)),)
 SPHINXOPTS    += "-q"
 endif
@@ -151,10 +155,11 @@ pdfdocs:
 
 else # HAVE_PDFLATEX
 
+pdfdocs: DENY_VF = XDG_CONFIG_HOME=$(FONTS_CONF_DENY_VF)
 pdfdocs: latexdocs
        @$(srctree)/scripts/sphinx-pre-install --version-check
        $(foreach var,$(SPHINXDIRS), \
-          $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" -C $(BUILDDIR)/$(var)/latex || exit; \
+          $(MAKE) PDFLATEX="$(PDFLATEX)" LATEXOPTS="$(LATEXOPTS)" $(DENY_VF) -C $(BUILDDIR)/$(var)/latex || sh $(srctree)/scripts/check-variable-fonts.sh || exit; \
           mkdir -p $(BUILDDIR)/$(var)/pdf; \
           mv $(subst .tex,.pdf,$(wildcard $(BUILDDIR)/$(var)/latex/*.tex)) $(BUILDDIR)/$(var)/pdf/; \
        )
index 872ac665223fbd51f7e06fd6fcf9eddd0de5a65f..94838c65c7d97130e829ddd5c80c38f6e55697a6 100644 (file)
@@ -427,7 +427,7 @@ their assorted primitives.
 
 This section shows a simple use of the core RCU API to protect a
 global pointer to a dynamically allocated structure.  More-typical
-uses of RCU may be found in listRCU.rst, arrayRCU.rst, and NMI-RCU.rst.
+uses of RCU may be found in listRCU.rst and NMI-RCU.rst.
 ::
 
        struct foo {
@@ -510,8 +510,8 @@ So, to sum up:
        data item.
 
 See checklist.rst for additional rules to follow when using RCU.
-And again, more-typical uses of RCU may be found in listRCU.rst,
-arrayRCU.rst, and NMI-RCU.rst.
+And again, more-typical uses of RCU may be found in listRCU.rst
+and NMI-RCU.rst.
 
 .. _4_whatisRCU:
 
index 17e6e9565156404e1adec007b20a31f097b20294..eaf9e66e472a38b25300ede5d34b2444451f063e 100644 (file)
@@ -1572,6 +1572,15 @@ PAGE_SIZE multiple when read back.
          pglazyfreed (npn)
                Amount of reclaimed lazyfree pages
 
+         zswpin
+               Number of pages moved in to memory from zswap.
+
+         zswpout
+               Number of pages moved out of memory to zswap.
+
+         zswpwb
+               Number of pages written from zswap to swap.
+
          thp_fault_alloc (npn)
                Number of transparent hugepages which were allocated to satisfy
                a page fault. This counter is not present when CONFIG_TRANSPARENT_HUGEPAGE
index cf1eeefdfc32f309cbcfc41b78f423b2e2e0cfc0..a92e10ec402e7d6a834976925f57847869771b6e 100644 (file)
@@ -67,8 +67,8 @@ arg4:
     will be performed for all tasks in the task group of ``pid``.
 
 arg5:
-    userspace pointer to an unsigned long for storing the cookie returned by
-    ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
+    userspace pointer to an unsigned long long for storing the cookie returned
+    by ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
 
 In order for a process to push a cookie to, or pull a cookie from a process, it
 is required to have the ptrace access mode: `PTRACE_MODE_READ_REALCREDS` to the
index e715bfc09879a7112ed9b8924c0bd3ff48e5896e..4bd3ce3ba171f223ff7b134d95db8780d6818daf 100644 (file)
@@ -135,7 +135,7 @@ and does not want to suffer the performance impact, one can always
 disable the mitigation with spec_rstack_overflow=off.
 
 Similarly, 'Mitigation: IBPB' is another full mitigation type employing
-an indrect branch prediction barrier after having applied the required
+an indirect branch prediction barrier after having applied the required
 microcode patch for one's system. This mitigation comes also at
 a performance cost.
 
index 902ecd92a29fbe83df18d32d1a8fe652c8277132..ddc4d235ebd0ece6e635dabcd089cb8c4e6f3e58 100644 (file)
                        arch-independent options, each of which is an
                        aggregation of existing arch-specific options.
 
+                       Note, "mitigations" is supported if and only if the
+                       kernel was built with CPU_MITIGATIONS=y.
+
                        off
                                Disable all optional CPU mitigations.  This
                                improves system performance, but it may also
 
        page_alloc.shuffle=
                        [KNL] Boolean flag to control whether the page allocator
-                       should randomize its free lists. The randomization may
-                       be automatically enabled if the kernel detects it is
-                       running on a platform with a direct-mapped memory-side
-                       cache, and this parameter can be used to
-                       override/disable that behavior. The state of the flag
-                       can be read from sysfs at:
+                       should randomize its free lists. This parameter can be
+                       used to enable/disable page randomization. The state of
+                       the flag can be read from sysfs at:
                        /sys/module/page_alloc/parameters/shuffle.
+                       This parameter is only available if CONFIG_SHUFFLE_PAGE_ALLOCATOR=y.
 
        page_owner=     [KNL,EARLY] Boot-time page_owner enabling option.
                        Storage of the information about who allocated
                norid           [S390] ignore the RID field and force use of
                                one PCI domain per PCI function
 
-       pcie_aspm=      [PCIE] Forcibly enable or disable PCIe Active State Power
+       pcie_aspm=      [PCIE] Forcibly enable or ignore PCIe Active State Power
                        Management.
-               off     Disable ASPM.
+               off     Don't touch ASPM configuration at all.  Leave any
+                       configuration done by firmware unchanged.
                force   Enable ASPM even on devices that claim not to support it.
                        WARNING: Forcing ASPM on may cause system lockups.
 
 
        prot_virt=      [S390] enable hosting protected virtual machines
                        isolated from the hypervisor (if hardware supports
-                       that).
+                       that). If enabled, the default kernel base address
+                       might be overridden even when Kernel Address Space
+                       Layout Randomization is disabled.
                        Format: <bool>
 
        psi=            [KNL] Enable or disable pressure stall information
                        delay, memory pressure or callback list growing too
                        big.
 
+       rcutree.rcu_normal_wake_from_gp= [KNL]
+                       Reduces a latency of synchronize_rcu() call. This approach
+                       maintains its own track of synchronize_rcu() callers, so it
+                       does not interact with regular callbacks because it does not
+                       use a call_rcu[_hurry]() path. Please note, this is for a
+                       normal grace period.
+
+                       How to enable it:
+
+                       echo 1 > /sys/module/rcutree/parameters/rcu_normal_wake_from_gp
+                       or pass a boot parameter "rcutree.rcu_normal_wake_from_gp=1"
+
+                       Default is 0.
+
        rcuscale.gp_async= [KNL]
                        Measure performance of asynchronous
                        grace-period primitives such as call_rcu().
                        - "tpm"
                        - "tee"
                        - "caam"
+                       - "dcp"
                        If not specified then it defaults to iterating through
                        the trust source list starting with TPM and assigns the
                        first trust source as a backend which is initialized
                        If not specified, "default" is used. In this case,
                        the RNG's choice is left to each individual trust source.
 
+       trusted.dcp_use_otp_key
+                       This is intended to be used in combination with
+                       trusted.source=dcp and will select the DCP OTP key
+                       instead of the DCP UNIQUE key blob encryption.
+
+       trusted.dcp_skip_zk_test
+                       This is intended to be used in combination with
+                       trusted.source=dcp and will disable the check if the
+                       blob key is all zeros. This is helpful for situations where
+                       having this key zero'ed is acceptable. E.g. in testing
+                       scenarios.
+
        tsc=            Disable clocksource stability checks for TSC.
                        Format: <string>
                        [x86] reliable: mark tsc clocksource as reliable, this
                        This can be changed after boot by writing to the
                        matching /sys/module/workqueue/parameters file. All
                        workqueues with the "default" affinity scope will be
-                       updated accordignly.
+                       updated accordingly.
 
        workqueue.debug_force_rr_cpu
                        Workqueue used to implicitly guarantee that work
index a639cac124777f123df7ce75bfd2229819e57c59..ad8e7a41f3b5d20fae4b7a369fba6adee63510fd 100644 (file)
@@ -308,7 +308,7 @@ limited by the ``advisor_max_cpu`` parameter. In addition there is also the
 ``advisor_target_scan_time`` parameter. This parameter sets the target time to
 scan all the KSM candidate pages. The parameter ``advisor_target_scan_time``
 decides how aggressive the scan time advisor scans candidate pages. Lower
-values make the scan time advisor to scan more aggresively. This is the most
+values make the scan time advisor to scan more aggressively. This is the most
 important parameter for the configuration of the scan time advisor.
 
 The initial value and the maximum value can be changed with
index 76b246ecf21b5143417937cafc8e527de3f676fc..946518355a2c2aa2a27cbe22f537d03719c0d23d 100644 (file)
@@ -42,12 +42,12 @@ The important basics
 --------------------
 
 
-What is a "regression" and what is the "no regressions rule"?
+What is a "regression" and what is the "no regressions" rule?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 It's a regression if some application or practical use case running fine with
 one Linux kernel works worse or not at all with a newer version compiled using a
-similar configuration. The "no regressions rule" forbids this to take place; if
+similar configuration. The "no regressions" rule forbids this to take place; if
 it happens by accident, developers that caused it are expected to quickly fix
 the issue.
 
@@ -173,7 +173,7 @@ Additional details about regressions
 ------------------------------------
 
 
-What is the goal of the "no regressions rule"?
+What is the goal of the "no regressions" rule?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Users should feel safe when updating kernel versions and not have to worry
@@ -199,8 +199,8 @@ Exceptions to this rule are extremely rare; in the past developers almost always
 turned out to be wrong when they assumed a particular situation was warranting
 an exception.
 
-Who ensures the "no regressions" is actually followed?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Who ensures the "no regressions" rule is actually followed?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The subsystem maintainers should take care of that, which are watched and
 supported by the tree maintainers -- e.g. Linus Torvalds for mainline and
index 20e4014139911dc8b9d788981c10534ca3838db6..5d1bc824978bf9f4504b743df0558ffc04dd5c39 100644 (file)
@@ -173,7 +173,7 @@ When accessing IDE registers with A6=1 (for example $84x),
 the timing will always be mode 0 8-bit compatible, no matter
 what you have selected in the speed register:
 
-781ns select, IOR/IOW after 4 clock cycles (=314ns) aktive.
+781ns select, IOR/IOW after 4 clock cycles (=314ns) active.
 
 All  the  timings with a very short select-signal (the 355ns
 fast  accesses)  depend  on the accelerator card used in the
index 73c79bf586fd60da8af67761959fe2add7db14df..e75a6e5d2505e6437c43b7efb5f87551db52ba45 100644 (file)
@@ -8,6 +8,7 @@ s390 Architecture
     cds
     3270
     driver-model
+    mm
     monreader
     qeth
     s390dbf
diff --git a/Documentation/arch/s390/mm.rst b/Documentation/arch/s390/mm.rst
new file mode 100644 (file)
index 0000000..084adad
--- /dev/null
@@ -0,0 +1,111 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+Memory Management
+=================
+
+Virtual memory layout
+=====================
+
+.. note::
+
+ - Some aspects of the virtual memory layout setup are not
+   clarified (number of page levels, alignment, DMA memory).
+
+ - Unused gaps in the virtual memory layout could be present
+   or not - depending on how partucular system is configured.
+   No page tables are created for the unused gaps.
+
+ - The virtual memory regions are tracked or untracked by KASAN
+   instrumentation, as well as the KASAN shadow memory itself is
+   created only when CONFIG_KASAN configuration option is enabled.
+
+::
+
+  =============================================================================
+  |    Physical      |   Virtual       | VM area description
+  =============================================================================
+  +- 0 --------------+- 0 --------------+
+  |                 | S390_lowcore     | Low-address memory
+  |                 +- 8 KB -----------+
+  |                 |                  |
+  |                 |                  |
+  |                 | ... unused gap   | KASAN untracked
+  |                 |                  |
+  +- AMODE31_START --+- AMODE31_START --+ .amode31 rand. phys/virt start
+  |.amode31 text/data|.amode31 text/data| KASAN untracked
+  +- AMODE31_END ----+- AMODE31_END ----+ .amode31 rand. phys/virt end (<2GB)
+  |                 |                  |
+  |                 |                  |
+  +- __kaslr_offset_phys               | kernel rand. phys start
+  |                 |                  |
+  | kernel text/data |                 |
+  |                 |                  |
+  +------------------+                 | kernel phys end
+  |                 |                  |
+  |                 |                  |
+  |                 |                  |
+  |                 |                  |
+  +- ident_map_size -+                 |
+                    |                  |
+                    |  ... unused gap  | KASAN untracked
+                    |                  |
+                    +- __identity_base + identity mapping start (>= 2GB)
+                    |                  |
+                    | identity         | phys == virt - __identity_base
+                    | mapping          | virt == phys + __identity_base
+                    |                  |
+                    |                  | KASAN tracked
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    |                  |
+                    +---- vmemmap -----+ 'struct page' array start
+                    |                  |
+                    | virtually mapped |
+                    | memory map       | KASAN untracked
+                    |                  |
+                    +- __abs_lowcore --+
+                    |                  |
+                    | Absolute Lowcore | KASAN untracked
+                    |                  |
+                    +- __memcpy_real_area
+                    |                  |
+                    |  Real Memory Copy| KASAN untracked
+                    |                  |
+                    +- VMALLOC_START --+ vmalloc area start
+                    |                  | KASAN untracked or
+                    |  vmalloc area    | KASAN shallowly populated in case
+                    |                  |       CONFIG_KASAN_VMALLOC=y
+                    +- MODULES_VADDR --+ modules area start
+                    |                  | KASAN allocated per module or
+                    |  modules area    | KASAN shallowly populated in case
+                    |                  |       CONFIG_KASAN_VMALLOC=y
+                    +- __kaslr_offset -+ kernel rand. virt start
+                    |                  | KASAN tracked
+                    | kernel text/data | phys == (kvirt - __kaslr_offset) +
+                    |                  |         __kaslr_offset_phys
+                    +- kernel .bss end + kernel rand. virt end
+                    |                  |
+                    |  ... unused gap  | KASAN untracked
+                    |                  |
+                    +------------------+ UltraVisor Secure Storage limit
+                    |                  |
+                    |  ... unused gap  | KASAN untracked
+                    |                  |
+                    +KASAN_SHADOW_START+ KASAN shadow memory start
+                    |                  |
+                    |   KASAN shadow   | KASAN untracked
+                    |                  |
+                    +------------------+ ASCE limit
index 929ee1c1c940072af235b233c9343e38e563be4e..ea744cbc8687e497274477fc839dd7930b620b18 100644 (file)
@@ -380,6 +380,36 @@ matrix device.
     control_domains:
       A read-only file for displaying the control domain numbers assigned to the
       vfio_ap mediated device.
+    ap_config:
+      A read/write file that, when written to, allows all three of the
+      vfio_ap mediated device's ap matrix masks to be replaced in one shot.
+      Three masks are given, one for adapters, one for domains, and one for
+      control domains. If the given state cannot be set then no changes are
+      made to the vfio-ap mediated device.
+
+      The format of the data written to ap_config is as follows:
+      {amask},{dmask},{cmask}\n
+
+      \n is a newline character.
+
+      amask, dmask, and cmask are masks identifying which adapters, domains,
+      and control domains should be assigned to the mediated device.
+
+      The format of a mask is as follows:
+      0xNN..NN
+
+      Where NN..NN is 64 hexadecimal characters representing a 256-bit value.
+      The leftmost (highest order) bit represents adapter/domain 0.
+
+      For an example set of masks that represent your mdev's current
+      configuration, simply cat ap_config.
+
+      Setting an adapter or domain number greater than the maximum allowed for
+      the system will result in an error.
+
+      This attribute is intended to be used by automation. End users would be
+      better served using the respective assign/unassign attributes for
+      adapters, domains, and control domains.
 
 * functions:
 
@@ -550,7 +580,7 @@ These are the steps:
    following Kconfig elements selected:
    * IOMMU_SUPPORT
    * S390
-   * ZCRYPT
+   * AP
    * VFIO
    * KVM
 
index 7ecd0bf4957b1a62ee9dc3172275d7ddaa931b33..ef1a4c2bf08bfe4ba5e0fc48b045cf6975f7e616 100644 (file)
@@ -41,7 +41,7 @@ Chapter 36. Coprocessor services
         submissions until they succeed; waiting for an outstanding CCB to complete is not necessary, and would
         not be a guarantee that a future submission would succeed.
 
-        The availablility of DAX coprocessor command service is indicated by the presence of the DAX virtual
+        The availability of DAX coprocessor command service is indicated by the presence of the DAX virtual
         device node in the guest MD (Section 8.24.17, “Database Analytics Accelerators (DAX) virtual-device
         node”).
 
index ae5c69e48b115180ab25f96ee67ea100dfe1b664..cec05ac464c1214138833bb637c5df89649b55cf 100644 (file)
@@ -138,7 +138,7 @@ Note this example does not include the sigaltstack preparation.
 Dynamic features in signal frames
 ---------------------------------
 
-Dynamcally enabled features are not written to the signal frame upon signal
+Dynamically enabled features are not written to the signal frame upon signal
 entry if the feature is in its initial configuration.  This differs from
 non-dynamic features which are always written regardless of their
 configuration.  Signal handlers can examine the XSAVE buffer's XSTATE_BV
index d7adc6d543db4f15456f3b061219acb3808de562..bee3b1bca9a7b46bcf9911f036c3280e77b4405a 100644 (file)
@@ -171,14 +171,14 @@ The rule of thumb:
  - RMW operations that are conditional are unordered on FAILURE,
    otherwise the above rules apply.
 
-Except of course when an operation has an explicit ordering like:
+Except of course when a successful operation has an explicit ordering like:
 
  {}_relaxed: unordered
  {}_acquire: the R of the RMW (or atomic_read) is an ACQUIRE
  {}_release: the W of the RMW (or atomic_set)  is a  RELEASE
 
 Where 'unordered' is against other memory locations. Address dependencies are
-not defeated.
+not defeated.  Conditional operations are still unordered on FAILURE.
 
 Fully ordered primitives are ordered against everything prior and everything
 subsequent. Therefore a fully ordered primitive is like having an smp_mb()
index e8a55f9d61dbcad2845e12769178680402689889..0bf31b6c4383c8b36d73f7361a6cdb87d1f5dba6 100644 (file)
@@ -203,13 +203,33 @@ setting the DMA mask fails.  In this manner, if a user of your driver reports
 that performance is bad or that the device is not even detected, you can ask
 them for the kernel messages to find out exactly why.
 
-The standard 64-bit addressing device would do something like this::
+The 24-bit addressing device would do something like this::
 
-       if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
+       if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(24))) {
                dev_warn(dev, "mydev: No suitable DMA available\n");
                goto ignore_this_device;
        }
 
+The standard 64-bit addressing device would do something like this::
+
+       dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))
+
+dma_set_mask_and_coherent() never return fail when DMA_BIT_MASK(64). Typical
+error code like::
+
+       /* Wrong code */
+       if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
+               dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))
+
+dma_set_mask_and_coherent() will never return failure when bigger than 32.
+So typical code like::
+
+       /* Recommended code */
+       if (support_64bit)
+               dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+       else
+               dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+
 If the device only supports 32-bit addressing for descriptors in the
 coherent allocations, but supports full 64-bits for streaming mappings
 it would look like this::
index e12f22ab33c7bb5e9340d84de1cc44ea561989f8..a15f9b1767a29aefa51493f044168dab10d0f963 100644 (file)
@@ -18,7 +18,7 @@ exceptions`_, `NMI and NMI-like exceptions`_.
 Non-instrumentable code - noinstr
 ---------------------------------
 
-Most instrumentation facilities depend on RCU, so intrumentation is prohibited
+Most instrumentation facilities depend on RCU, so instrumentation is prohibited
 for entry code before RCU starts watching and exit code after RCU stops
 watching. In addition, many architectures must save and restore register state,
 which means that (for example) a breakpoint in the breakpoint entry code would
index 3062f37d119b0f33828267df9b7532eb25ce76e8..1979c5dd32fe4defddaf583ab6fd3dc9036a0c26 100644 (file)
@@ -4,7 +4,7 @@
 Printk Index
 ============
 
-There are many ways how to monitor the state of the system. One important
+There are many ways to monitor the state of the system. One important
 source of information is the system log. It provides a lot of information,
 including more or less important warnings and error messages.
 
@@ -101,7 +101,7 @@ their own wrappers adding __printk_index_emit().
 
 Only few subsystem specific wrappers have been updated so far,
 for example, dev_printk(). As a result, the printk formats from
-some subsystes can be missing in the printk index.
+some subsystems can be missing in the printk index.
 
 
 Subsystem specific prefix
index ed73c612174d4c99d3329cc1443b553537e049db..bcc370c876be9538c5020c6a14e8584d9090ebdf 100644 (file)
@@ -671,7 +671,7 @@ configuration, worker pools and how workqueues map to the pools: ::
   events_unbound           unbound  9  9 10 10  8
   events_freezable         percpu   0  2  4  6
   events_power_efficient   percpu   0  2  4  6
-  events_freezable_power_  percpu   0  2  4  6
+  events_freezable_pwr_ef  percpu   0  2  4  6
   rcu_gp                   percpu   0  2  4  6
   rcu_par_gp               percpu   0  2  4  6
   slub_flushwq             percpu   0  2  4  6
@@ -694,7 +694,7 @@ Use tools/workqueue/wq_monitor.py to monitor workqueue operations: ::
   events_unbound              38306     0      0.1       -       7       -       -
   events_freezable                0     0      0.0       0       0       -       -
   events_power_efficient      29598     0      0.2       0       0       -       -
-  events_freezable_power_        10     0      0.0       0       0       -       -
+  events_freezable_pwr_ef        10     0      0.0       0       0       -       -
   sock_diag_events                0     0      0.0       0       0       -       -
 
                               total  infl  CPUtime  CPUhog CMW/RPR  mayday rescued
@@ -704,7 +704,7 @@ Use tools/workqueue/wq_monitor.py to monitor workqueue operations: ::
   events_unbound              38322     0      0.1       -       7       -       -
   events_freezable                0     0      0.0       0       0       -       -
   events_power_efficient      29603     0      0.2       0       0       -       -
-  events_freezable_power_        10     0      0.0       0       0       -       -
+  events_freezable_pwr_ef        10     0      0.0       0       0       -       -
   sock_diag_events                0     0      0.0       0       0       -       -
 
   ...
index 94b6802ab0ab23635479f6061fa8ed8b196c7306..02143f060b22f05e3243ca1e71910d7e2fb1358a 100644 (file)
@@ -91,6 +91,16 @@ the below options are available:
   behaviour when encountering a data race is deemed safe.  Please see
   `"Marking Shared-Memory Accesses" in the LKMM`_ for more information.
 
+* Similar to ``data_race(...)``, the type qualifier ``__data_racy`` can be used
+  to document that all data races due to accesses to a variable are intended
+  and should be ignored by KCSAN::
+
+    struct foo {
+        ...
+        int __data_racy stats_counter;
+        ...
+    };
+
 * Disabling data race detection for entire functions can be accomplished by
   using the function attribute ``__no_kcsan``::
 
diff --git a/Documentation/devicetree/bindings/access-controllers/access-controllers.yaml b/Documentation/devicetree/bindings/access-controllers/access-controllers.yaml
new file mode 100644 (file)
index 0000000..99e2865
--- /dev/null
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/access-controllers/access-controllers.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic Domain Access Controllers
+
+maintainers:
+  - Oleksii Moisieiev <oleksii_moisieiev@epam.com>
+
+description: |+
+  Common access controllers properties
+
+  Access controllers are in charge of stating which of the hardware blocks under
+  their responsibility (their domain) can be accesssed by which compartment. A
+  compartment can be a cluster of CPUs (or coprocessors), a range of addresses
+  or a group of hardware blocks. An access controller's domain is the set of
+  resources covered by the access controller.
+
+  This device tree binding can be used to bind devices to their access
+  controller provided by access-controllers property. In this case, the device
+  is a consumer and the access controller is the provider.
+
+  An access controller can be represented by any node in the device tree and
+  can provide one or more configuration parameters, needed to control parameters
+  of the consumer device. A consumer node can refer to the provider by phandle
+  and a set of phandle arguments, specified by '#access-controller-cells'
+  property in the access controller node.
+
+  Access controllers are typically used to set/read the permissions of a
+  hardware block and grant access to it. Any of which depends on the access
+  controller. The capabilities of each access controller are defined by the
+  binding of the access controller device.
+
+  Each node can be a consumer for the several access controllers.
+
+# always select the core schema
+select: true
+
+properties:
+  "#access-controller-cells":
+    description:
+      Number of cells in an access-controllers specifier;
+      Can be any value as specified by device tree binding documentation
+      of a particular provider. The node is an access controller.
+
+  access-controller-names:
+    $ref: /schemas/types.yaml#/definitions/string-array
+    description:
+      A list of access-controllers names, sorted in the same order as
+      access-controllers entries. Consumer drivers will use
+      access-controller-names to match with existing access-controllers entries.
+
+  access-controllers:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description:
+      A list of access controller specifiers, as defined by the
+      bindings of the access-controllers provider.
+
+additionalProperties: true
+
+examples:
+  - |
+    clock_controller: access-controllers@50000 {
+        reg = <0x50000 0x400>;
+        #access-controller-cells = <2>;
+    };
+
+    bus_controller: bus@60000 {
+        reg = <0x60000 0x10000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+        #access-controller-cells = <3>;
+
+        uart4: serial@60100 {
+            reg = <0x60100 0x400>;
+            clocks = <&clk_serial>;
+            access-controllers = <&clock_controller 1 2>,
+                                 <&bus_controller 1 3 5>;
+            access-controller-names = "clock", "bus";
+        };
+    };
index 4cc4e67546819b2776b6a1d15e9d85f2f3b0c16f..d925e7a3b5ef992a8f4412f077612b3da460f616 100644 (file)
@@ -53,6 +53,7 @@ properties:
       - description: BCM4709 based boards
         items:
           - enum:
+              - asus,rt-ac3200
               - asus,rt-ac87u
               - buffalo,wxr-1900dhp
               - linksys,ea9200
@@ -67,6 +68,7 @@ properties:
         items:
           - enum:
               - asus,rt-ac3100
+              - asus,rt-ac5300
               - asus,rt-ac88u
               - dlink,dir-885l
               - dlink,dir-890l
index 39e3c248f5b7dd7769717ae2ce8c5684042a3363..1f84407a73e49fd6c5db051d281457cd453b658a 100644 (file)
@@ -46,6 +46,30 @@ properties:
       - compatible
       - "#clock-cells"
 
+  gpio:
+    type: object
+    additionalProperties: false
+
+    properties:
+      compatible:
+        const: raspberrypi,firmware-gpio
+
+      gpio-controller: true
+
+      "#gpio-cells":
+        const: 2
+        description:
+          The first cell is the pin number, and the second cell is used to
+          specify the gpio polarity (GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW).
+
+      gpio-line-names:
+        minItems: 8
+
+    required:
+      - compatible
+      - gpio-controller
+      - "#gpio-cells"
+
   reset:
     type: object
     additionalProperties: false
@@ -96,6 +120,12 @@ examples:
             #clock-cells = <1>;
         };
 
+        expgpio: gpio {
+            compatible = "raspberrypi,firmware-gpio";
+            gpio-controller;
+            #gpio-cells = <2>;
+        };
+
         reset: reset {
             compatible = "raspberrypi,firmware-reset";
             #reset-cells = <1>;
index 0027201e19f8b05f83970087eda4e3da9726e0d8..6d185d09cb6ae8e5893221fac3c058292ade86b8 100644 (file)
@@ -813,6 +813,14 @@ properties:
           - const: tq,imx6ull-tqma6ull2l      # MCIMX6Y2, LGA SoM variant
           - const: fsl,imx6ull
 
+      - description: Seeed Stuido i.MX6ULL SoM on dev boards
+        items:
+          - enum:
+              - seeed,imx6ull-seeed-npi-emmc
+              - seeed,imx6ull-seeed-npi-nand
+          - const: seeed,imx6ull-seeed-npi
+          - const: fsl,imx6ull
+
       - description: i.MX6ULZ based Boards
         items:
           - enum:
@@ -1050,6 +1058,7 @@ properties:
           - enum:
               - beacon,imx8mp-beacon-kit  # i.MX8MP Beacon Development Kit
               - dmo,imx8mp-data-modul-edm-sbc # i.MX8MP eDM SBC
+              - emcraft,imx8mp-navqp      # i.MX8MP Emcraft Systems NavQ+ Kit
               - fsl,imx8mp-evk            # i.MX8MP EVK Board
               - gateworks,imx8mp-gw71xx-2x # i.MX8MP Gateworks Board
               - gateworks,imx8mp-gw72xx-2x # i.MX8MP Gateworks Board
@@ -1218,7 +1227,6 @@ properties:
           - enum:
               - einfochips,imx8qxp-ai_ml  # i.MX8QXP AI_ML Board
               - fsl,imx8qxp-mek           # i.MX8QXP MEK Board
-              - toradex,colibri-imx8x     # Colibri iMX8X Modules
           - const: fsl,imx8qxp
 
       - description: i.MX8DXL based Boards
@@ -1227,7 +1235,7 @@ properties:
               - fsl,imx8dxl-evk           # i.MX8DXL EVK Board
           - const: fsl,imx8dxl
 
-      - description: i.MX8QXP Boards with Toradex Colibri iMX8X Modules
+      - description: i.MX8QXP/i.MX8DX Boards with Toradex Colibri iMX8X Modules
         items:
           - enum:
               - toradex,colibri-imx8x-aster   # Colibri iMX8X Module on Aster Board
@@ -1235,7 +1243,9 @@ properties:
               - toradex,colibri-imx8x-iris    # Colibri iMX8X Module on Iris Board
               - toradex,colibri-imx8x-iris-v2 # Colibri iMX8X Module on Iris Board V2
           - const: toradex,colibri-imx8x
-          - const: fsl,imx8qxp
+          - enum:
+              - fsl,imx8qxp
+              - fsl,imx8dx
 
       - description:
           TQMa8Xx is a series of SOM featuring NXP i.MX8X system-on-chip
@@ -1536,6 +1546,12 @@ properties:
               - nxp,s32g274a-rdb2
           - const: nxp,s32g2
 
+      - description: S32G3 based Boards
+        items:
+          - enum:
+              - nxp,s32g399a-rdb3
+          - const: nxp,s32g3
+
       - description: S32V234 based Boards
         items:
           - enum:
index c24ad0968f3ef17cb3cee3782d7550f261e0346e..7f06b10802449126990a0febd01037e2e03300d7 100644 (file)
@@ -61,10 +61,6 @@ properties:
   mboxes:
     minItems: 2
 
-  ti,system-reboot-controller:
-    description: Determines If system reboot can be triggered by SoC reboot
-    type: boolean
-
   ti,host-id:
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
@@ -94,7 +90,6 @@ examples:
   - |
     pmmc: system-controller@2921800 {
       compatible = "ti,k2g-sci";
-      ti,system-reboot-controller;
       mbox-names = "rx", "tx";
       mboxes = <&msgmgr 5 2>,
                <&msgmgr 0 0>;
index 66beaac60e1dc4b1e23fe41badee1f7c01cf4405..ae885414b1811ee34e2b74a59716141347ad1a67 100644 (file)
@@ -137,6 +137,7 @@ properties:
               - microsoft,dempsey
               - microsoft,makepeace
               - microsoft,moneypenny
+              - motorola,falcon
               - samsung,s3ve3g
           - const: qcom,msm8226
 
@@ -184,13 +185,16 @@ properties:
               - oneplus,bacon
               - samsung,klte
               - sony,xperia-castor
+              - sony,xperia-leo
           - const: qcom,msm8974pro
           - const: qcom,msm8974
 
       - items:
-          - const: qcom,msm8916-mtp
-          - const: qcom,msm8916-mtp/1
-          - const: qcom,msm8916
+          - enum:
+              - samsung,kltechn
+          - const: samsung,klte
+          - const: qcom,msm8974pro
+          - const: qcom,msm8974
 
       - items:
           - enum:
@@ -200,6 +204,8 @@ properties:
               - gplus,fl8005a
               - huawei,g7
               - longcheer,l8910
+              - longcheer,l8150
+              - qcom,msm8916-mtp
               - samsung,a3u-eur
               - samsung,a5u-eur
               - samsung,e5
@@ -220,11 +226,6 @@ properties:
               - yiming,uz801-v3
           - const: qcom,msm8916
 
-      - items:
-          - const: longcheer,l8150
-          - const: qcom,msm8916-v1-qrd/9-v1
-          - const: qcom,msm8916
-
       - items:
           - enum:
               - motorola,potter
@@ -1003,6 +1004,7 @@ properties:
               - qcom,sm8550-hdk
               - qcom,sm8550-mtp
               - qcom,sm8550-qrd
+              - sony,pdx234
           - const: qcom,sm8550
 
       - items:
index fcf7316ecd74cdb9e34e8eca98e3a2a65b882e28..e04c213a0dee45c6feb7a81432c264fe75011e7b 100644 (file)
@@ -49,6 +49,11 @@ properties:
               - anbernic,rg-arc-s
           - const: rockchip,rk3566
 
+      - description: ArmSoM Sige7 board
+        items:
+          - const: armsom,sige7
+          - const: rockchip,rk3588
+
       - description: Asus Tinker board
         items:
           - const: asus,rk3288-tinker
@@ -198,6 +203,13 @@ properties:
           - const: firefly,rk3568-roc-pc
           - const: rockchip,rk3568
 
+      - description: Forlinx FET3588-C SoM
+        items:
+          - enum:
+              - forlinx,ok3588-c
+          - const: forlinx,fet3588-c
+          - const: rockchip,rk3588
+
       - description: FriendlyElec NanoPi R2 series boards
         items:
           - enum:
@@ -236,6 +248,11 @@ properties:
           - const: friendlyarm,nanopc-t6
           - const: rockchip,rk3588
 
+      - description: GameForce Chi
+        items:
+          - const: gameforce,chi
+          - const: rockchip,rk3326
+
       - description: GeekBuying GeekBox
         items:
           - const: geekbuying,geekbox
@@ -631,7 +648,7 @@ properties:
           - const: phytec,rk3288-phycore-som
           - const: rockchip,rk3288
 
-      - description: Pine64 PinebookPro
+      - description: Pine64 Pinebook Pro
         items:
           - const: pine64,pinebook-pro
           - const: rockchip,rk3399
@@ -644,7 +661,7 @@ properties:
           - const: pine64,pinenote
           - const: rockchip,rk3566
 
-      - description: Pine64 PinePhonePro
+      - description: Pine64 PinePhone Pro
         items:
           - const: pine64,pinephone-pro
           - const: rockchip,rk3399
@@ -682,7 +699,7 @@ properties:
           - const: pine64,quartzpro64
           - const: rockchip,rk3588
 
-      - description: Pine64 SoQuartz SoM
+      - description: Pine64 SOQuartz
         items:
           - enum:
               - pine64,soquartz-blade
@@ -700,12 +717,17 @@ properties:
               - powkiddy,x55
           - const: rockchip,rk3566
 
+      - description: Protonic MECSBC board
+        items:
+          - const: prt,mecsbc
+          - const: rockchip,rk3568
+
       - description: QNAP TS-433-4G 4-Bay NAS
         items:
           - const: qnap,ts433
           - const: rockchip,rk3568
 
-      - description: Radxa Compute Module 3(CM3)
+      - description: Radxa Compute Module 3 (CM3)
         items:
           - enum:
               - radxa,cm3-io
@@ -767,22 +789,27 @@ properties:
           - const: radxa,rockpis
           - const: rockchip,rk3308
 
-      - description: Radxa Rock2 Square
+      - description: Radxa Rock 2 Square
         items:
           - const: radxa,rock2-square
           - const: rockchip,rk3288
 
-      - description: Radxa ROCK3 Model A
+      - description: Radxa ROCK 3A
         items:
           - const: radxa,rock3a
           - const: rockchip,rk3568
 
-      - description: Radxa ROCK 5 Model A
+      - description: Radxa ROCK 3C
+        items:
+          - const: radxa,rock-3c
+          - const: rockchip,rk3566
+
+      - description: Radxa ROCK 5A
         items:
           - const: radxa,rock-5a
           - const: rockchip,rk3588s
 
-      - description: Radxa ROCK 5 Model B
+      - description: Radxa ROCK 5B
         items:
           - const: radxa,rock-5b
           - const: rockchip,rk3588
@@ -927,6 +954,11 @@ properties:
           - const: turing,rk1
           - const: rockchip,rk3588
 
+      - description: WolfVision PF5 mainboard
+        items:
+          - const: wolfvision,rk3568-pf5
+          - const: rockchip,rk3568
+
       - description: Xunlong Orange Pi 5 Plus
         items:
           - const: xunlong,orangepi-5-plus
index 09d835db6db57af63019633ece6f74b0b8d7d215..c6d0d8d81ed4deb9dd9a79d52a91c669c74e324d 100644 (file)
@@ -56,6 +56,21 @@ properties:
           - const: anbernic,rg-nano
           - const: allwinner,sun8i-v3s
 
+      - description: Anbernic RG35XX (2024)
+      - items:
+          - const: anbernic,rg35xx-2024
+          - const: allwinner,sun50i-h700
+
+      - description: Anbernic RG35XX Plus
+      - items:
+          - const: anbernic,rg35xx-plus
+          - const: allwinner,sun50i-h700
+
+      - description: Anbernic RG35XX H
+      - items:
+          - const: anbernic,rg35xx-h
+          - const: allwinner,sun50i-h700
+
       - description: Amarula A64 Relic
         items:
           - const: amarula,a64-relic
@@ -774,6 +789,11 @@ properties:
           - const: pocketbook,touch-lux-3
           - const: allwinner,sun5i-a13
 
+      - description: PocketBook 614 Plus
+        items:
+          - const: pocketbook,614-plus
+          - const: allwinner,sun5i-a13
+
       - description: Point of View Protab2-IPS9
         items:
           - const: pov,protab2-ips9
@@ -860,6 +880,11 @@ properties:
           - const: allwinner,sl631
           - const: allwinner,sun8i-v3
 
+      - description: Tanix TX1
+        items:
+          - const: oranth,tanix-tx1
+          - const: allwinner,sun50i-h616
+
       - description: Tanix TX6
         items:
           - const: oranth,tanix-tx6
diff --git a/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml b/Documentation/devicetree/bindings/bus/st,stm32-etzpc.yaml
new file mode 100644 (file)
index 0000000..d12b62a
--- /dev/null
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/st,stm32-etzpc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STM32 Extended TrustZone protection controller
+
+description: |
+  The ETZPC configures TrustZone security in a SoC having bus masters and
+  devices with programmable-security attributes (securable resources).
+
+maintainers:
+  - Gatien Chevallier <gatien.chevallier@foss.st.com>
+
+select:
+  properties:
+    compatible:
+      contains:
+        const: st,stm32-etzpc
+  required:
+    - compatible
+
+properties:
+  compatible:
+    items:
+      - const: st,stm32-etzpc
+      - const: simple-bus
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the firewall ID associated to the peripheral.
+
+patternProperties:
+  "^.*@[0-9a-f]+$":
+    description: Peripherals
+    type: object
+
+    additionalProperties: true
+
+    required:
+      - access-controllers
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - "#access-controller-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    // In this example, the usart2 device refers to rifsc as its access
+    // controller.
+    // Access rights are verified before creating devices.
+
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/stm32mp13-clks.h>
+    #include <dt-bindings/reset/stm32mp13-resets.h>
+
+    etzpc: bus@5c007000 {
+        compatible = "st,stm32-etzpc", "simple-bus";
+        reg = <0x5c007000 0x400>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        #access-controller-cells = <1>;
+        ranges;
+
+        usart2: serial@4c001000 {
+            compatible = "st,stm32h7-uart";
+            reg = <0x4c001000 0x400>;
+            interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&rcc USART2_K>;
+            resets = <&rcc USART2_R>;
+            wakeup-source;
+            dmas = <&dmamux1 43 0x400 0x5>,
+                    <&dmamux1 44 0x400 0x1>;
+            dma-names = "rx", "tx";
+            access-controllers = <&etzpc 17>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml b/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml
new file mode 100644 (file)
index 0000000..20acd1a
--- /dev/null
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/st,stm32mp25-rifsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STM32 Resource isolation framework security controller
+
+maintainers:
+  - Gatien Chevallier <gatien.chevallier@foss.st.com>
+
+description: |
+  Resource isolation framework (RIF) is a comprehensive set of hardware blocks
+  designed to enforce and manage isolation of STM32 hardware resources like
+  memory and peripherals.
+
+  The RIFSC (RIF security controller) is composed of three sets of registers,
+  each managing a specific set of hardware resources:
+    - RISC registers associated with RISUP logic (resource isolation device unit
+      for peripherals), assign all non-RIF aware peripherals to zero, one or
+      any security domains (secure, privilege, compartment).
+    - RIMC registers: associated with RIMU logic (resource isolation master
+      unit), assign all non RIF-aware bus master to one security domain by
+      setting secure, privileged and compartment information on the system bus.
+      Alternatively, the RISUP logic controlling the device port access to a
+      peripheral can assign target bus attributes to this peripheral master port
+      (supported attribute: CID).
+    - RISC registers associated with RISAL logic (resource isolation device unit
+      for address space - Lite version), assign address space subregions to one
+      security domains (secure, privilege, compartment).
+
+select:
+  properties:
+    compatible:
+      contains:
+        const: st,stm32mp25-rifsc
+  required:
+    - compatible
+
+properties:
+  compatible:
+    items:
+      - const: st,stm32mp25-rifsc
+      - const: simple-bus
+
+  reg:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+  "#access-controller-cells":
+    const: 1
+    description:
+      Contains the firewall ID associated to the peripheral.
+
+patternProperties:
+  "^.*@[0-9a-f]+$":
+    description: Peripherals
+    type: object
+
+    additionalProperties: true
+
+    required:
+      - access-controllers
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - "#access-controller-cells"
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    // In this example, the usart2 device refers to rifsc as its domain
+    // controller.
+    // Access rights are verified before creating devices.
+
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    rifsc: bus@42080000 {
+        compatible = "st,stm32mp25-rifsc", "simple-bus";
+        reg = <0x42080000 0x1000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        #access-controller-cells = <1>;
+        ranges;
+
+        usart2: serial@400e0000 {
+              compatible = "st,stm32h7-uart";
+              reg = <0x400e0000 0x400>;
+              interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+              clocks = <&ck_flexgen_08>;
+              access-controllers = <&rifsc 32>;
+        };
+    };
index 1d2bcea41c8588b0dbe10c6c870e3d75f09b220b..caf442ead24bda57e531420d8a7d8de8713032ae 100644 (file)
@@ -30,16 +30,18 @@ properties:
       - google,gs101-cmu-top
       - google,gs101-cmu-apm
       - google,gs101-cmu-misc
+      - google,gs101-cmu-hsi0
+      - google,gs101-cmu-hsi2
       - google,gs101-cmu-peric0
       - google,gs101-cmu-peric1
 
   clocks:
     minItems: 1
-    maxItems: 3
+    maxItems: 5
 
   clock-names:
     minItems: 1
-    maxItems: 3
+    maxItems: 5
 
   "#clock-cells":
     const: 1
@@ -72,6 +74,55 @@ allOf:
           items:
             - const: oscclk
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: google,gs101-cmu-hsi0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24.576 MHz)
+            - description: HSI0 bus clock (from CMU_TOP)
+            - description: DPGTC (from CMU_TOP)
+            - description: USB DRD controller clock (from CMU_TOP)
+            - description: USB Display Port debug clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: dpgtc
+            - const: usb31drd
+            - const: usbdpdbg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - google,gs101-cmu-hsi2
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24.576 MHz)
+            - description: High Speed Interface bus clock (from CMU_TOP)
+            - description: High Speed Interface pcie clock (from CMU_TOP)
+            - description: High Speed Interface ufs clock (from CMU_TOP)
+            - description: High Speed Interface mmc clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: bus
+            - const: pcie
+            - const: ufs
+            - const: mmc
+
   - if:
       properties:
         compatible:
index 0ddeb8a9a7a018bda6769f03e05f6373a348e8ae..27354658d05448c1559e5db67b842f2dae90df3d 100644 (file)
@@ -46,6 +46,10 @@ properties:
   power-domains:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index ac480765cde061f497f7da77218f4b55b5f05a35..82231841409521c230a290a65b14088890d6ad41 100644 (file)
@@ -51,6 +51,10 @@ properties:
   power-domains:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index a95445f408700b74881ff5bb55da3cfff4d4de86..397e810008bd60e5a023addd4e8024fe1dc90992 100644 (file)
@@ -348,15 +348,6 @@ properties:
         # Yes Optoelectronics YTC700TLAG-05-201C 7" TFT LCD panel
       - yes-optoelectronics,ytc700tlag-05-201c
 
-  backlight: true
-  ddc-i2c-bus: true
-  enable-gpios: true
-  port: true
-  power-supply: true
-  no-hpd: true
-  hpd-gpios: true
-  data-mapping: true
-
 if:
   not:
     properties:
@@ -367,7 +358,7 @@ then:
   properties:
     data-mapping: false
 
-additionalProperties: false
+unevaluatedProperties: false
 
 required:
   - compatible
index 94c5242c03b288da8aeb37c8c4b1ddf94d814564..3563378a01af47fe3593ff8183230bc6c9186f3a 100644 (file)
@@ -177,6 +177,15 @@ allOf:
 
       required:
         - reg-names
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - nvidia,tegra194-host1x
+    then:
+      properties:
+        dma-coherent: true
   - if:
       properties:
         compatible:
@@ -226,6 +235,8 @@ allOf:
             use. Should be a mapping of IDs 0..n to IOMMU entries corresponding to
             usable stream IDs.
 
+        dma-coherent: true
+
       required:
         - reg-names
 
index 329847ef096a1fb5a28749296288136c5e2bc31c..ff935a0068ec5888001ca0e7249f6bbb6c07d778 100644 (file)
@@ -82,6 +82,10 @@ properties:
     description: if defined, it indicates that the controller
       supports memory-to-memory transfer
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index e722fbcd8a5f432ad11482cdeaf8df55a21a2dfc..ddf82bf1e71aebdd09591dce906206417e8289b2 100644 (file)
@@ -28,6 +28,10 @@ properties:
   resets:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 4591523b51a0d4ede50b30fd9ed014a2338a512c..7de2c29606e5aa4ab985273950468471df83fa96 100644 (file)
@@ -247,6 +247,37 @@ properties:
       reg:
         const: 0x18
 
+  protocol@19:
+    type: object
+    allOf:
+      - $ref: '#/$defs/protocol-node'
+      - $ref: /schemas/pinctrl/pinctrl.yaml
+
+    unevaluatedProperties: false
+
+    properties:
+      reg:
+        const: 0x19
+
+    patternProperties:
+      '-pins$':
+        type: object
+        allOf:
+          - $ref: /schemas/pinctrl/pincfg-node.yaml#
+          - $ref: /schemas/pinctrl/pinmux-node.yaml#
+        unevaluatedProperties: false
+
+        description:
+          A pin multiplexing sub-node describes how to configure a
+          set of pins in some desired function.
+          A single sub-node may define several pin configurations.
+          This sub-node is using the default pinctrl bindings to configure
+          pin multiplexing and using SCMI protocol to apply a specified
+          configuration.
+
+    required:
+      - reg
+
 additionalProperties: false
 
 $defs:
@@ -355,7 +386,7 @@ examples:
 
             scmi_dvfs: protocol@13 {
                 reg = <0x13>;
-                #clock-cells = <1>;
+                #power-domain-cells = <1>;
 
                 mboxes = <&mhuB 1 0>,
                          <&mhuB 1 1>;
@@ -401,6 +432,25 @@ examples:
             scmi_powercap: protocol@18 {
                 reg = <0x18>;
             };
+
+            scmi_pinctrl: protocol@19 {
+                reg = <0x19>;
+
+                i2c2-pins {
+                    groups = "g_i2c2_a", "g_i2c2_b";
+                    function = "f_i2c2";
+                };
+
+                mdio-pins {
+                    groups = "g_avb_mdio";
+                    drive-strength = <24>;
+                };
+
+                keys_pins: keys-pins {
+                    pins = "gpio_5_17", "gpio_5_20", "gpio_5_22", "gpio_2_1";
+                    bias-pull-up;
+                };
+            };
         };
     };
 
@@ -468,7 +518,7 @@ examples:
                 reg = <0x13>;
                 linaro,optee-channel-id = <1>;
                 shmem = <&cpu_optee_lpri0>;
-                #clock-cells = <1>;
+                #power-domain-cells = <1>;
             };
 
             scmi_clk0: protocol@14 {
diff --git a/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt b/Documentation/devicetree/bindings/gpio/raspberrypi,firmware-gpio.txt
deleted file mode 100644 (file)
index ce97265..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-Raspberry Pi GPIO expander
-
-The Raspberry Pi 3 GPIO expander is controlled by the VC4 firmware. The
-firmware exposes a mailbox interface that allows the ARM core to control the
-GPIO lines on the expander.
-
-The Raspberry Pi GPIO expander node must be a child node of the Raspberry Pi
-firmware node.
-
-Required properties:
-
-- compatible : Should be "raspberrypi,firmware-gpio"
-- gpio-controller : Marks the device node 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:
-  0 = active high
-  1 = active low
-
-Example:
-
-firmware: firmware-rpi {
-       compatible = "raspberrypi,bcm2835-firmware";
-       mboxes = <&mailbox>;
-
-       expgpio: gpio {
-                compatible = "raspberrypi,firmware-gpio";
-                gpio-controller;
-                #gpio-cells = <2>;
-        };
-};
index 1b31b87c1800a00d8935d261432117ea5d601191..8fd8be76875ec12b71da052d6ef5614dd944e7ed 100644 (file)
@@ -127,6 +127,10 @@ properties:
 
   wakeup-source: true
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 995cbf8cefc66f71ec5768b05c14c98e8619f8ce..ec34c48d48782b9a72b714a37d7264c57c501f74 100644 (file)
@@ -93,6 +93,10 @@ properties:
   '#size-cells':
     const: 0
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 allOf:
   - if:
       properties:
index 1970503389aa9aacf88c356477b4ad6aff5e0bbc..c1b1324fa13295dc30ba6c8621659cbe862da37f 100644 (file)
@@ -59,6 +59,10 @@ properties:
       If not, SPI CLKOUT frequency will not be accurate.
     maximum: 20000000
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 04045b932bd221fb7c3b00b45bbd773b1f92e9b1..b15de4eb209c53d400782e4d0ff3aba4e53471ac 100644 (file)
@@ -45,6 +45,10 @@ properties:
   '#size-cells':
     const: 0
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 additionalProperties: false
 
 required:
index c13c10c8d65da26cfc7faa0517f28332a2c9d8ae..eed0df9d3a2322d9818709588ca4c335f5f689d5 100644 (file)
@@ -42,7 +42,7 @@ allOf:
       properties:
         compatible:
           contains:
-            const: maxim,max30100
+            const: maxim,max30102
     then:
       properties:
         maxim,green-led-current-microamp: false
index 2314a9a146509889f0e982e6dc3f723a2e72ccf1..1d930d9e10fd83496e84d6e415adcd01193e73a2 100644 (file)
@@ -29,6 +29,10 @@ properties:
       - const: cec
       - const: hdmi-cec
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 6b3e413cedb259ef71f7726ad1bb84c3068cbdca..34147127192fd830c92d4f5e0fc657e5ce2ce4f1 100644 (file)
@@ -36,6 +36,10 @@ properties:
   resets:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
   port:
     $ref: /schemas/graph.yaml#/$defs/port-base
     unevaluatedProperties: false
index b8611bc8756c48d0bd7dd1887b6f6bcf13320b20..73726c65cfb940b498b8ee5119f464ab7684b26f 100644 (file)
@@ -30,6 +30,10 @@ properties:
   clocks:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/memory-controllers/samsung,s5pv210-dmc.yaml b/Documentation/devicetree/bindings/memory-controllers/samsung,s5pv210-dmc.yaml
new file mode 100644 (file)
index 0000000..c0e4705
--- /dev/null
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/samsung,s5pv210-dmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5Pv210 SoC Dynamic Memory Controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzk@kernel.org>
+
+description:
+  Dynamic Memory Controller interfaces external JEDEC DDR-type SDRAM.
+
+properties:
+  compatible:
+    const: samsung,s5pv210-dmc
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    memory-controller@f0000000 {
+        compatible = "samsung,s5pv210-dmc";
+        reg = <0xf0000000 0x1000>;
+    };
index 84ac6f50a6fc3ff23968beb1d3c7b1f251692186..706e45eb4d279f9723f9e9b758b7bb4318999f45 100644 (file)
@@ -50,6 +50,10 @@ properties:
       Reflects the memory layout with four integer values per bank. Format:
       <bank-number> 0 <address of the bank> <size>
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 patternProperties:
   "^.*@[0-4],[a-f0-9]+$":
     additionalProperties: true
index 27329c5dc38e6e1bb87ea50798eda2afb3cdb4a3..d41308856408fcb1124239f5e726e6d44f2de190 100644 (file)
@@ -44,6 +44,10 @@ properties:
 
   wakeup-source: true
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
   pwm:
     type: object
     additionalProperties: false
index f84e09a5743b77c5be31ac4f6f3a979c0122d44d..b0e438ff49509ea0a62242c859f9a9bb31060e19 100644 (file)
@@ -67,6 +67,10 @@ properties:
   "#size-cells":
     const: 0
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
   pwm:
     type: object
     additionalProperties: false
index 940b126881674629eb00679e223bbd4900b4c7cc..8f62e2c7fa6414015fb8bceb86a8807e4a7192cd 100644 (file)
@@ -79,6 +79,10 @@ properties:
           - const: rx
           - const: tx
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
   power-domains: true
 
   resets:
index f9ffb963d6b122fb5fccec50b8a244261299bf1a..c4887522e8fe97c3947357b4dbd4ecf20ee8100a 100644 (file)
@@ -118,6 +118,10 @@ properties:
   phys:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index e74502a0afe867d8ae5289796d1b8de0d02ba10a..3202dc7967c5b686d1c74194daca4c315f8d87a7 100644 (file)
@@ -337,8 +337,8 @@ allOf:
           minItems: 4
 
         clocks:
-          minItems: 34
-          maxItems: 34
+          minItems: 24
+          maxItems: 24
 
         clock-names:
           items:
@@ -351,18 +351,6 @@ allOf:
             - const: ethwarp_wocpu1
             - const: ethwarp_wocpu0
             - const: esw
-            - const: netsys0
-            - const: netsys1
-            - const: sgmii_tx250m
-            - const: sgmii_rx250m
-            - const: sgmii2_tx250m
-            - const: sgmii2_rx250m
-            - const: top_usxgmii0_sel
-            - const: top_usxgmii1_sel
-            - const: top_sgm0_sel
-            - const: top_sgm1_sel
-            - const: top_xfi_phy0_xtal_sel
-            - const: top_xfi_phy1_xtal_sel
             - const: top_eth_gmii_sel
             - const: top_eth_refck_50m_sel
             - const: top_eth_sys_200m_sel
@@ -375,16 +363,10 @@ allOf:
             - const: top_netsys_sync_250m_sel
             - const: top_netsys_ppefb_250m_sel
             - const: top_netsys_warp_sel
-            - const: wocpu1
-            - const: wocpu0
             - const: xgp1
             - const: xgp2
             - const: xgp3
 
-        mediatek,sgmiisys:
-          minItems: 2
-          maxItems: 2
-
 patternProperties:
   "^mac@[0-1]$":
     type: object
index fc8c96b08d7dca709fa5e0fe2a34afbdff3eea74..f2714b5b6cf426bf50f1662007df12ab4073d78d 100644 (file)
@@ -93,6 +93,10 @@ properties:
       select RCC clock instead of ETH_REF_CLK.
     type: boolean
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - clocks
index 24a3dbde223bc35dd4520b7d40db34dd2902b1ab..ceea122ae1a6a7aab97aa2b28af271f2010b677f 100644 (file)
@@ -55,6 +55,10 @@ properties:
     description: number of clock cells for ck_usbo_48m consumer
     const: 0
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 # Required child nodes:
 
 patternProperties:
index d476de82e5c3f487b0275d1f2d8d8b5a79a6a116..4d5a957fa232eb55d0bd71ea887eefec35b60063 100644 (file)
@@ -120,7 +120,9 @@ additionalProperties:
         slew-rate: true
         gpio-hog: true
         gpios: true
+        input: true
         input-enable: true
+        output-enable: true
         output-high: true
         output-low: true
         line-name: true
index 05f4ad2c7d3a1d854abda35271aaebb1f20b2dc3..6ceaffb45dc968041660b50080d9e2e6923da999 100644 (file)
@@ -30,6 +30,10 @@ properties:
   vdda-supply:
     description: phandle to the vdda input analog voltage.
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 717f6b321f884d39dc197796da8a4e33e59c3f1d..340d01d481d12ce8664a60db42182ddaf0d1385b 100644 (file)
@@ -37,6 +37,10 @@ properties:
     description: If set, the RNG configuration in RNG_CR, RNG_HTCR and
                   RNG_NSCR will be locked.
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 62f97da1b2fd7c944442c17127897d154d6c4acb..2ed526139269c2d3fcadfcd135308ac2ec43c8d6 100644 (file)
@@ -73,6 +73,10 @@ properties:
     enum: [1, 2, 4, 8, 12, 14, 16]
     default: 8
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 allOf:
   - $ref: rs485.yaml#
   - $ref: serial.yaml#
index 4310bae6c58ef320a3af1abf01a86c64719a6afa..4512390f90f04387f7aef36a6416bb96615ef0f1 100644 (file)
@@ -58,20 +58,6 @@ patternProperties:
 required:
   - compatible
 
-allOf:
-  - if:
-      not:
-        properties:
-          compatible:
-            contains:
-              enum:
-                - qcom,sm8450-pmic-glink
-                - qcom,sm8550-pmic-glink
-                - qcom,x1e80100-pmic-glink
-    then:
-      properties:
-        orientation-gpios: false
-
 additionalProperties: false
 
 examples:
index 74bb92e315541343ece7680d3629669516f5d424..fd6db0ca98eb7e56d7399f55c408844d5e782805 100644 (file)
@@ -116,8 +116,8 @@ examples:
 
             bluetooth {
                 compatible = "qcom,wcnss-bt";
-                /* BD address 00:11:22:33:44:55 */
-                local-bd-address = [ 55 44 33 22 11 00 ];
+                /* Updated by boot firmware (little-endian order) */
+                local-bd-address = [ 00 00 00 00 00 00 ];
             };
 
             wifi {
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas,r9a09g057-sys.yaml
new file mode 100644 (file)
index 0000000..ebbf0c9
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/renesas/renesas,r9a09g057-sys.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2H(P) System Controller (SYS)
+
+maintainers:
+  - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description: |
+  The RZ/V2H(P) SYS (System Controller) controls the overall
+  configuration of the LSI and supports the following functions,
+  - Trust zone control
+  - Extend access by specific masters to address beyond 4GB space
+  - GBETH configuration
+  - Control of settings and states of SRAM/PCIe/CM33/CA55/CR8/xSPI/ADC/TSU
+  - LSI version
+  - WDT stop control
+  - General registers
+
+properties:
+  compatible:
+    const: renesas,r9a09g057-sys
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    sys: system-controller@10430000 {
+        compatible = "renesas,r9a09g057-sys";
+        reg = <0x10430000 0x10000>;
+        clocks = <&cpg 1>;
+        resets = <&cpg 1>;
+    };
index c1ce4da2dc325e586fb8cf7c0d1d0400be321daf..09d3ce97efa2a3daabf141fa5dbac505156ed103 100644 (file)
@@ -513,6 +513,14 @@ properties:
               - renesas,rzv2mevk2   # RZ/V2M Eval Board v2.0
           - const: renesas,r9a09g011
 
+      - description: RZ/V2H(P) (R9A09G057)
+        items:
+          - enum:
+              - renesas,r9a09g057h41 # RZ/V2H
+              - renesas,r9a09g057h42 # RZ/V2H with Mali-G31 support
+              - renesas,r9a09g057h44 # RZ/V2HP with Mali-G31 + Mali-C55 support
+          - const: renesas,r9a09g057
+
 additionalProperties: true
 
 ...
index c0c6ce8fc7863e1bc942fa3cea9c66906d1cdca1..3ca220582897f5b36dbeb8aeccbadfa6bdd9bd98 100644 (file)
@@ -15,6 +15,7 @@ properties:
       - items:
           - enum:
               - google,gs101-apm-sysreg
+              - google,gs101-hsi2-sysreg
               - google,gs101-peric0-sysreg
               - google,gs101-peric1-sysreg
               - samsung,exynos3-sysreg
@@ -72,6 +73,7 @@ allOf:
         compatible:
           contains:
             enum:
+              - google,gs101-hsi2-sysreg
               - google,gs101-peric0-sysreg
               - google,gs101-peric1-sysreg
               - samsung,exynos850-cmgp-sysreg
index 41a62fd2ae1ffb4f2afaa58d204797a2b15e91ec..c1fa379f5f3ea1388ed9e54ea8fef66d4645d673 100644 (file)
@@ -20,6 +20,11 @@ Optional properties:
   a GPIO spec for the external headphone detect pin. If jd-mode = 0,
   we will get the JD status by getting the value of hp-detect-gpios.
 
+- cbj-sleeve-gpios:
+  a GPIO spec to control the external combo jack circuit to tie the sleeve/ring2
+  contacts to the ground or floating. It could avoid some electric noise from the
+  active speaker jacks.
+
 - realtek,in2-differential
   Boolean. Indicate MIC2 input are differential, rather than single-ended.
 
@@ -68,6 +73,7 @@ codec: rt5650@1a {
        compatible = "realtek,rt5650";
        reg = <0x1a>;
        hp-detect-gpios = <&gpio 19 0>;
+       cbj-sleeve-gpios = <&gpio 20 0>;
        interrupt-parent = <&gpio>;
        interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
        realtek,dmic-en = "true";
index b9111d375b93f52de81452e2a119c833ee2f9e22..8978f6bd63e59eed24243695c170f814299ba24d 100644 (file)
@@ -65,6 +65,10 @@ properties:
     $ref: audio-graph-port.yaml#
     unevaluatedProperties: false
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - "#sound-dai-cells"
index 59df8a832310da21acab762924d6a012ea836ee7..b46a4778807d452593b18c1ede5786f839c3063b 100644 (file)
@@ -48,6 +48,10 @@ properties:
   clock-names:
     maxItems: 3
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index bc48151b9adbdc0e219230dd9af1b8ca0ecf4f3e..3dedc81ec12f67ae539d30782656fd2b79837695 100644 (file)
@@ -50,6 +50,10 @@ properties:
   resets:
     maxItems: 1
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - "#sound-dai-cells"
index 8bba965a9ae64e5ce50b0cbc6a2edb1c684b6c34..3f1a27efff80e5e95c9fbbbd1e3907cfdb3bf65e 100644 (file)
@@ -46,6 +46,10 @@ properties:
       - const: tx
       - const: rx
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 4bd9aeb8120859152de1eeb93acf96874a0e27c9..a55c8633c32ce9c9fe4306695e31b66a15baf0a1 100644 (file)
@@ -52,6 +52,10 @@ properties:
       - const: rx
       - const: tx
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 required:
   - compatible
   - reg
index 3ab4434b73524ffbf4a1776efdab3878d0ade565..af7720dc4a12ce435d85e83d76911ac26db01e95 100644 (file)
@@ -32,6 +32,7 @@ properties:
           - enum:
               - infineon,slb9673
               - nuvoton,npct75x
+              - st,st33ktpm2xi2c
           - const: tcg,tpm-tis-i2c
 
       - description: TPM 1.2 and 2.0 chips with vendor-specific I²C interface
index 0a5c98ea711d489cf6b8e81b1c2697e11ee98bc4..88c077673c8bc86657f8424c76629b7115aab00e 100644 (file)
@@ -172,6 +172,10 @@ properties:
 
   tpl-support: true
 
+  access-controllers:
+    minItems: 1
+    maxItems: 2
+
 dependencies:
   port: [ usb-role-switch ]
   role-switch-default-mode: [ usb-role-switch ]
index 2d3589d284b220a0623a538cedd094b70c2797d1..0a6e7ac1b37e28f2a7b284d37a9131eef9b7f0dc 100644 (file)
@@ -33,6 +33,7 @@ properties:
               - fsl,imx7ulp-usbmisc
               - fsl,imx8mm-usbmisc
               - fsl,imx8mn-usbmisc
+              - fsl,imx8ulp-usbmisc
           - const: fsl,imx7d-usbmisc
           - const: fsl,imx6q-usbmisc
       - items:
index b97d298b3eb695ba016d98b0715d692c23bb6ce1..460c729f6e3009f04dd61f6bb590738a7737dbf5 100644 (file)
@@ -151,6 +151,8 @@ patternProperties:
     description: ARM Ltd.
   "^armadeus,.*":
     description: ARMadeus Systems SARL
+  "^armsom,.*":
+    description: ArmSoM Technology Co., Ltd.
   "^arrow,.*":
     description: Arrow Electronics
   "^artesyn,.*":
@@ -438,6 +440,8 @@ patternProperties:
     description: Dongguan EmbedFire Electronic Technology Co., Ltd.
   "^embest,.*":
     description: Shenzhen Embest Technology Co., Ltd.
+  "^emcraft,.*":
+    description: Emcraft Systems
   "^emlid,.*":
     description: Emlid, Ltd.
   "^emmicro,.*":
@@ -1627,6 +1631,8 @@ patternProperties:
     description: Wondermedia Technologies, Inc.
   "^wobo,.*":
     description: Wobo
+  "^wolfvision,.*":
+    description: WolfVision GmbH
   "^x-powers,.*":
     description: X-Powers
   "^xen,.*":
index 5da0046f7059ba167c8098e7ef0aec47d89cd753..204b025f13492db38770479ae9bd6c95125d8668 100644 (file)
@@ -61,7 +61,7 @@ DESCRIPTION
 ***********
 
 
-Convert a C header or source file (C_FILE), into a ReStructured Text
+Convert a C header or source file (C_FILE), into a reStructuredText
 included via ..parsed-literal block with cross-references for the
 documentation files that describe the API. It accepts an optional
 EXCEPTIONS_FILE with describes what elements will be either ignored or
index 3eac11b7eb01fb1491938ad4a7859dadededfc10..b33ebe1ec9ed4b23c057e6a48ee8f89da1482531 100644 (file)
@@ -196,8 +196,8 @@ eisa_bus.disable_dev
 virtual_root.force_probe
        Force the probing code to probe EISA slots even when it cannot find an
        EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
-       (don't force), and set to 1 (force probing) when either
-       CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set.
+       (don't force), and set to 1 (force probing) when
+       CONFIG_EISA_VLB_PRIMING is set.
 
 Random notes
 ============
index 74347c14a70bb17603b3e6cc0a695e01a9b5825b..a0d681f26a2e81b9753269621bf0d62bb7a68cf9 100644 (file)
@@ -462,7 +462,7 @@ statements is reduced. This is also reflected in the assembly code.
 Analysis 3
 ==========
 
-Very weird. Guess it has to do with caching or instruction parallellism
+Very weird. Guess it has to do with caching or instruction parallelism
 or so. I also tried on an eeePC (Celeron, clocked at 900 Mhz). Interesting
 observation was that this one is only 30% slower (according to time)
 executing the code as my 3Ghz D920 processor.
index 64b231d125e0fc0f5396e18022898086b2d5be40..ec92ea2c82cde2b7640a339ecd9968719e916b49 100644 (file)
@@ -259,7 +259,7 @@ attributes for Serial Attached SCSI, a variant of SATA aimed at large
 high-end systems.
 
 The SAS transport class contains common code to deal with SAS HBAs, an
-aproximated representation of SAS topologies in the driver model, and
+approximated representation of SAS topologies in the driver model, and
 various sysfs attributes to expose these topologies and management
 interfaces to userspace.
 
index fb41768696ecbc74ed10bc97832882172d5beb49..89f9c37bb979a4f6570821a4c06e223815503856 100644 (file)
@@ -422,7 +422,7 @@ USBDEVFS_CONNECTINFO
 
 USBDEVFS_GET_SPEED
     Returns the speed of the device. The speed is returned as a
-    nummerical value in accordance with enum usb_device_speed
+    numerical value in accordance with enum usb_device_speed
 
     File modification time is not updated by this request.
 
index f48bfa02981348682ea38df8bcc996b06fb721df..6b18833e2e6955633f87b427b5fd3930a583a866 100644 (file)
@@ -68,7 +68,7 @@ The expected flow for the consumers:
 can be enabled for the device.
 2. Call `amd_wbrf_register_notifier` to register for notification
 of frequency band change(add or remove) from other producers.
-3. Call the `amd_wbrf_retrieve_freq_band` initally to retrieve
+3. Call the `amd_wbrf_retrieve_freq_band` initially to retrieve
 current active frequency bands considering some producers may broadcast
 such information before the consumer is up.
 4. On receiving a notification for frequency band change, run
index 05ea387bc9fbcf49ba53dd4f13332207b15766ad..6fdf0b02df430f8dcadc96a69a7926992534f47c 100644 (file)
@@ -44,7 +44,7 @@ For our purposes all operations fall in 6 classes:
        * decide which of the source and target need to be locked.
          The source needs to be locked if it's a non-directory, target - if it's
          a non-directory or about to be removed.
-       * take the locks that need to be taken (exlusive), in inode pointer order
+       * take the locks that need to be taken (exclusive), in inode pointer order
          if need to take both (that can happen only when both source and target
          are non-directories - the source because it wouldn't need to be locked
          otherwise and the target because mixing directory and non-directory is
@@ -234,7 +234,7 @@ among the children, in some order.  But that is also impossible, since
 neither of the children is a descendent of another.
 
 That concludes the proof, since the set of operations with the
-properties requiered for a minimal deadlock can not exist.
+properties required for a minimal deadlock can not exist.
 
 Note that the check for having a common ancestor in cross-directory
 rename is crucial - without it a deadlock would be possible.  Indeed,
index 1be76ef117b3f80051713c8dc24f0f2568248075..f2b44c2400c6969b58d036ccde4fc72dea1b576d 100644 (file)
@@ -858,7 +858,7 @@ be misspelled d_alloc_anon().
 
 **mandatory**
 
-[should've been added in 2016] stale comment in finish_open() nonwithstanding,
+[should've been added in 2016] stale comment in finish_open() notwithstanding,
 failure exits in ->atomic_open() instances should *NOT* fput() the file,
 no matter what.  Everything is handled by the caller.
 
@@ -989,7 +989,7 @@ This mechanism would only work for a single device so the block layer couldn't
 find the owning superblock of any additional devices.
 
 In the old mechanism reusing or creating a superblock for a racing mount(2) and
-umount(2) relied on the file_system_type as the holder. This was severly
+umount(2) relied on the file_system_type as the holder. This was severely
 underdocumented however:
 
 (1) Any concurrent mounter that managed to grab an active reference on an
index 5298611e00ee9dbf65dc91e61ba61f38cdd121eb..f9f525f4c0dda7c8a681dde3bd7bd95eb5ec25fa 100644 (file)
@@ -107,7 +107,7 @@ Other documentation
 
 There are several unsorted documents that don't seem to fit on other parts
 of the documentation body, or may require some adjustments and/or conversion
-to ReStructured Text format, or are simply too old.
+to reStructuredText format, or are simply too old.
 
 .. toctree::
    :maxdepth: 1
index 658d37860d3974b03aea570e6c212c79a09aa491..6c666f3422ea3a3cf3b3f214c950ea2163d1a8fa 100644 (file)
@@ -21,6 +21,51 @@ Atomic-RMW-ops-are-atomic-WRT-atomic_set.litmus
     Test that atomic_set() cannot break the atomicity of atomic RMWs.
     NOTE: Require herd7 7.56 or later which supports "(void)expr".
 
+cmpxchg-fail-ordered-1.litmus
+    Demonstrate that a failing cmpxchg() operation acts as a full barrier
+    when followed by smp_mb__after_atomic().
+
+cmpxchg-fail-ordered-2.litmus
+    Demonstrate that a failing cmpxchg() operation acts as an acquire
+    operation when followed by smp_mb__after_atomic().
+
+cmpxchg-fail-unordered-1.litmus
+    Demonstrate that a failing cmpxchg() operation does not act as a
+    full barrier.
+
+cmpxchg-fail-unordered-2.litmus
+    Demonstrate that a failing cmpxchg() operation does not act as an
+    acquire operation.
+
+
+locking (/locking directory)
+----------------------------
+
+DCL-broken.litmus
+    Demonstrates that double-checked locking needs more than just
+    the obvious lock acquisitions and releases.
+
+DCL-fixed.litmus
+    Demonstrates corrected double-checked locking that uses
+    smp_store_release() and smp_load_acquire() in addition to the
+    obvious lock acquisitions and releases.
+
+RM-broken.litmus
+    Demonstrates problems with "roach motel" locking, where code is
+    freely moved into lock-based critical sections.  This example also
+    shows how to use the "filter" clause to discard executions that
+    would be excluded by other code not modeled in the litmus test.
+    Note also that this "roach motel" optimization is emulated by
+    physically moving P1()'s two reads from x under the lock.
+
+    What is a roach motel?  This is from an old advertisement for
+    a cockroach trap, much later featured in one of the "Men in
+    Black" movies.  "The roaches check in.  They don't check out."
+
+RM-fixed.litmus
+    The counterpart to RM-broken.litmus, showing P0()'s two loads from
+    x safely outside of the critical section.
+
 
 RCU (/rcu directory)
 --------------------
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-1.litmus
new file mode 100644 (file)
index 0000000..c0f93dc
--- /dev/null
@@ -0,0 +1,35 @@
+C cmpxchg-fail-ordered-1
+
+(*
+ * Result: Never
+ *
+ * Demonstrate that a failing cmpxchg() operation will act as a full
+ * barrier when followed by smp_mb__after_atomic().
+ *)
+
+{}
+
+P0(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(z, 1, 0);
+       smp_mb__after_atomic();
+       r0 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*y, 1);
+       r1 = cmpxchg(z, 1, 0);
+       smp_mb__after_atomic();
+       r0 = READ_ONCE(*x);
+}
+
+locations[0:r1;1:r1]
+exists (0:r0=0 /\ 1:r0=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-ordered-2.litmus
new file mode 100644 (file)
index 0000000..5c06054
--- /dev/null
@@ -0,0 +1,30 @@
+C cmpxchg-fail-ordered-2
+
+(*
+ * Result: Never
+ *
+ * Demonstrate use of smp_mb__after_atomic() to make a failing cmpxchg
+ * operation have acquire ordering.
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(y, 0, 1);
+}
+
+P1(int *x, int *y)
+{
+       int r1;
+       int r2;
+
+       r1 = cmpxchg(y, 0, 1);
+       smp_mb__after_atomic();
+       r2 = READ_ONCE(*x);
+}
+
+exists (0:r1=0 /\ 1:r1=1 /\ 1:r2=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-1.litmus
new file mode 100644 (file)
index 0000000..39ea1f5
--- /dev/null
@@ -0,0 +1,34 @@
+C cmpxchg-fail-unordered-1
+
+(*
+ * Result: Sometimes
+ *
+ * Demonstrate that a failing cmpxchg() operation does not act as a
+ * full barrier.  (In contrast, a successful cmpxchg() does act as a
+ * full barrier.)
+ *)
+
+{}
+
+P0(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(z, 1, 0);
+       r0 = READ_ONCE(*y);
+}
+
+P1(int *x, int *y, int *z)
+{
+       int r0;
+       int r1;
+
+       WRITE_ONCE(*y, 1);
+       r1 = cmpxchg(z, 1, 0);
+       r0 = READ_ONCE(*x);
+}
+
+locations[0:r1;1:r1]
+exists (0:r0=0 /\ 1:r0=0)
diff --git a/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus b/Documentation/litmus-tests/atomic/cmpxchg-fail-unordered-2.litmus
new file mode 100644 (file)
index 0000000..61aab24
--- /dev/null
@@ -0,0 +1,30 @@
+C cmpxchg-fail-unordered-2
+
+(*
+ * Result: Sometimes
+ *
+ * Demonstrate that a failing cmpxchg() operation does not act as either
+ * an acquire release operation.  (In contrast, a successful cmpxchg()
+ * does act as both an acquire and a release operation.)
+ *)
+
+{}
+
+P0(int *x, int *y)
+{
+       int r1;
+
+       WRITE_ONCE(*x, 1);
+       r1 = cmpxchg(y, 0, 1);
+}
+
+P1(int *x, int *y)
+{
+       int r1;
+       int r2;
+
+       r1 = cmpxchg(y, 0, 1);
+       r2 = READ_ONCE(*x);
+}
+
+exists (0:r1=0 /\ 1:r1=1 /\ 1:r2=0)
index b517ee28a9552dc9887e7423e58463aa906d4f64..60d350d08362b058dc1edc55fb50b9e7e56bcb1d 100644 (file)
@@ -80,7 +80,7 @@ to the dentry cache with::
 
 Debugging options may require the minimum possible slab order to increase as
 a result of storing the metadata (for example, caches with PAGE_SIZE object
-sizes).  This has a higher liklihood of resulting in slab allocation errors
+sizes).  This has a higher likelihood of resulting in slab allocation errors
 in low memory situations or if there's high fragmentation of memory.  To
 switch off debugging for such caches by default, use::
 
index 8e4d19adee8cd17eae831db73692c9237b5e0ad1..4e702ac8bf66bfe2cce7e96852eea04b363d1b96 100644 (file)
@@ -1144,6 +1144,12 @@ attribute-sets:
       -
         name: mcast-querier-state
         type: binary
+      -
+        name: fdb-n-learned
+        type: u32
+      -
+        name: fdb-max-learned
+        type: u32
   -
     name: linkinfo-brport-attrs
     name-prefix: ifla-brport-
index ce6753a674f336b59785f105b2e419547724bd75..49ba1410cfce73f4c6e88e8f72b95c91dad7acaf 100644 (file)
@@ -284,7 +284,7 @@ What else is there to known about regressions?
 Check out Documentation/admin-guide/reporting-regressions.rst, it covers a lot
 of other aspects you want might want to be aware of:
 
- * the purpose of the "no regressions rule"
+ * the purpose of the "no regressions" rule
 
  * what issues actually qualify as regression
 
index 1704f1c686d0a8b5f078400603387b4468ffc90f..edf90bbe30f43dd61e4e67193dda41e244ee9c14 100644 (file)
@@ -6,29 +6,29 @@ Everything you ever wanted to know about Linux -stable releases
 Rules on what kind of patches are accepted, and which ones are not, into the
 "-stable" tree:
 
- - It or an equivalent fix must already exist in Linus' tree (upstream).
- - It must be obviously correct and tested.
- - It cannot be bigger than 100 lines, with context.
- - It must follow the
-   :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
-   rules.
- - It must either fix a real bug that bothers people or just add a device ID.
-   To elaborate on the former:
-
-   - It fixes a problem like an oops, a hang, data corruption, a real security
-     issue, a hardware quirk, a build error (but not for things marked
-     CONFIG_BROKEN), or some "oh, that's not good" issue.
-   - Serious issues as reported by a user of a distribution kernel may also
-     be considered if they fix a notable performance or interactivity issue.
-     As these fixes are not as obvious and have a higher risk of a subtle
-     regression they should only be submitted by a distribution kernel
-     maintainer and include an addendum linking to a bugzilla entry if it
-     exists and additional information on the user-visible impact.
-   - No "This could be a problem..." type of things like a "theoretical race
-     condition", unless an explanation of how the bug can be exploited is also
-     provided.
-   - No "trivial" fixes without benefit for users (spelling changes, whitespace
-     cleanups, etc).
+- It or an equivalent fix must already exist in Linux mainline (upstream).
+- It must be obviously correct and tested.
+- It cannot be bigger than 100 lines, with context.
+- It must follow the
+  :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
+  rules.
+- It must either fix a real bug that bothers people or just add a device ID.
+  To elaborate on the former:
+
+  - It fixes a problem like an oops, a hang, data corruption, a real security
+    issue, a hardware quirk, a build error (but not for things marked
+    CONFIG_BROKEN), or some "oh, that's not good" issue.
+  - Serious issues as reported by a user of a distribution kernel may also
+    be considered if they fix a notable performance or interactivity issue.
+    As these fixes are not as obvious and have a higher risk of a subtle
+    regression they should only be submitted by a distribution kernel
+    maintainer and include an addendum linking to a bugzilla entry if it
+    exists and additional information on the user-visible impact.
+  - No "This could be a problem..." type of things like a "theoretical race
+    condition", unless an explanation of how the bug can be exploited is also
+    provided.
+  - No "trivial" fixes without benefit for users (spelling changes, whitespace
+    cleanups, etc).
 
 
 Procedure for submitting patches to the -stable tree
@@ -42,11 +42,11 @@ Procedure for submitting patches to the -stable tree
 
 There are three options to submit a change to -stable trees:
 
- 1. Add a 'stable tag' to the description of a patch you then submit for
-    mainline inclusion.
- 2. Ask the stable team to pick up a patch already mainlined.
- 3. Submit a patch to the stable team that is equivalent to a change already
-    mainlined.
+1. Add a 'stable tag' to the description of a patch you then submit for
+   mainline inclusion.
+2. Ask the stable team to pick up a patch already mainlined.
+3. Submit a patch to the stable team that is equivalent to a change already
+   mainlined.
 
 The sections below describe each of the options in more detail.
 
@@ -68,82 +68,72 @@ Option 1
 ********
 
 To have a patch you submit for mainline inclusion later automatically picked up
-for stable trees, add the tag
+for stable trees, add this tag in the sign-off area::
 
-.. code-block:: none
+  Cc: stable@vger.kernel.org
 
-     Cc: stable@vger.kernel.org
+Use ``Cc: stable@kernel.org`` instead when fixing unpublished vulnerabilities:
+it reduces the chance of accidentally exposing the fix to the public by way of
+'git send-email', as mails sent to that address are not delivered anywhere.
 
-in the sign-off area. Once the patch is mainlined it will be applied to the
-stable tree without anything else needing to be done by the author or
-subsystem maintainer.
+Once the patch is mainlined it will be applied to the stable tree without
+anything else needing to be done by the author or subsystem maintainer.
 
-To sent additional instructions to the stable team, use a shell-style inline
-comment:
+To send additional instructions to the stable team, use a shell-style inline
+comment to pass arbitrary or predefined notes:
 
- * To specify any additional patch prerequisites for cherry picking use the
-   following format in the sign-off area:
+* Specify any additional patch prerequisites for cherry picking::
 
-   .. code-block:: none
+    Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
+    Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
+    Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
+    Cc: <stable@vger.kernel.org> # 3.3.x
+    Signed-off-by: Ingo Molnar <mingo@elte.hu>
 
-     Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
-     Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
-     Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
-     Cc: <stable@vger.kernel.org> # 3.3.x
-     Signed-off-by: Ingo Molnar <mingo@elte.hu>
+  The tag sequence has the meaning of::
 
-   The tag sequence has the meaning of:
+    git cherry-pick a1f84a3
+    git cherry-pick 1b9508f
+    git cherry-pick fd21073
+    git cherry-pick <this commit>
 
-   .. code-block:: none
+  Note that for a patch series, you do not have to list as prerequisites the
+  patches present in the series itself. For example, if you have the following
+  patch series::
 
-     git cherry-pick a1f84a3
-     git cherry-pick 1b9508f
-     git cherry-pick fd21073
-     git cherry-pick <this commit>
+    patch1
+    patch2
 
-   Note that for a patch series, you do not have to list as prerequisites the
-   patches present in the series itself. For example, if you have the following
-   patch series:
+  where patch2 depends on patch1, you do not have to list patch1 as
+  prerequisite of patch2 if you have already marked patch1 for stable
+  inclusion.
 
-   .. code-block:: none
+* Point out kernel version prerequisites::
 
-     patch1
-     patch2
+    Cc: <stable@vger.kernel.org> # 3.3.x
 
-   where patch2 depends on patch1, you do not have to list patch1 as
-   prerequisite of patch2 if you have already marked patch1 for stable
-   inclusion.
+  The tag has the meaning of::
 
- * For patches that may have kernel version prerequisites specify them using
-   the following format in the sign-off area:
+    git cherry-pick <this commit>
 
-   .. code-block:: none
+  For each "-stable" tree starting with the specified version.
 
-     Cc: <stable@vger.kernel.org> # 3.3.x
+  Note, such tagging is unnecessary if the stable team can derive the
+  appropriate versions from Fixes: tags.
 
-   The tag has the meaning of:
+* Delay pick up of patches::
 
-   .. code-block:: none
+    Cc: <stable@vger.kernel.org> # after -rc3
 
-     git cherry-pick <this commit>
+* Point out known problems::
 
-   For each "-stable" tree starting with the specified version.
+    Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.3
 
-   Note, such tagging is unnecessary if the stable team can derive the
-   appropriate versions from Fixes: tags.
+There furthermore is a variant of the stable tag you can use to make the stable
+team's backporting tools (e.g AUTOSEL or scripts that look for commits
+containing a 'Fixes:' tag) ignore a change::
 
- * To delay pick up of patches, use the following format:
-
-   .. code-block:: none
-
-     Cc: <stable@vger.kernel.org> # after 4 weeks in mainline
-
- * For any other requests, just add a note to the stable tag. This for example
-   can be used to point out known problems:
-
-   .. code-block:: none
-
-     Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.3
+     Cc: <stable+noautosel@kernel.org> # reason goes here, and must be present
 
 .. _option_2:
 
@@ -163,17 +153,13 @@ Option 3
 Send the patch, after verifying that it follows the above rules, to
 stable@vger.kernel.org and mention the kernel versions you wish it to be applied
 to. When doing so, you must note the upstream commit ID in the changelog of your
-submission with a separate line above the commit text, like this:
-
-.. code-block:: none
-
-    commit <sha1> upstream.
+submission with a separate line above the commit text, like this::
 
-or alternatively:
+  commit <sha1> upstream.
 
-.. code-block:: none
+Or alternatively::
 
-    [ Upstream commit <sha1> ]
+  [ Upstream commit <sha1> ]
 
 If the submitted patch deviates from the original upstream patch (for example
 because it had to be adjusted for the older API), this must be very clearly
@@ -194,55 +180,55 @@ developers and by the relevant subsystem maintainer.
 Review cycle
 ------------
 
- - When the -stable maintainers decide for a review cycle, the patches will be
-   sent to the review committee, and the maintainer of the affected area of
-   the patch (unless the submitter is the maintainer of the area) and CC: to
-   the linux-kernel mailing list.
- - The review committee has 48 hours in which to ACK or NAK the patch.
- - If the patch is rejected by a member of the committee, or linux-kernel
-   members object to the patch, bringing up issues that the maintainers and
-   members did not realize, the patch will be dropped from the queue.
- - The ACKed patches will be posted again as part of release candidate (-rc)
-   to be tested by developers and testers.
- - Usually only one -rc release is made, however if there are any outstanding
-   issues, some patches may be modified or dropped or additional patches may
-   be queued. Additional -rc releases are then released and tested until no
-   issues are found.
- - Responding to the -rc releases can be done on the mailing list by sending
-   a "Tested-by:" email with any testing information desired. The "Tested-by:"
-   tags will be collected and added to the release commit.
- - At the end of the review cycle, the new -stable release will be released
-   containing all the queued and tested patches.
- - Security patches will be accepted into the -stable tree directly from the
-   security kernel team, and not go through the normal review cycle.
-   Contact the kernel security team for more details on this procedure.
+- When the -stable maintainers decide for a review cycle, the patches will be
+  sent to the review committee, and the maintainer of the affected area of
+  the patch (unless the submitter is the maintainer of the area) and CC: to
+  the linux-kernel mailing list.
+- The review committee has 48 hours in which to ACK or NAK the patch.
+- If the patch is rejected by a member of the committee, or linux-kernel
+  members object to the patch, bringing up issues that the maintainers and
+  members did not realize, the patch will be dropped from the queue.
+- The ACKed patches will be posted again as part of release candidate (-rc)
+  to be tested by developers and testers.
+- Usually only one -rc release is made, however if there are any outstanding
+  issues, some patches may be modified or dropped or additional patches may
+  be queued. Additional -rc releases are then released and tested until no
+  issues are found.
+- Responding to the -rc releases can be done on the mailing list by sending
+  a "Tested-by:" email with any testing information desired. The "Tested-by:"
+  tags will be collected and added to the release commit.
+- At the end of the review cycle, the new -stable release will be released
+  containing all the queued and tested patches.
+- Security patches will be accepted into the -stable tree directly from the
+  security kernel team, and not go through the normal review cycle.
+  Contact the kernel security team for more details on this procedure.
 
 
 Trees
 -----
 
- - The queues of patches, for both completed versions and in progress
-   versions can be found at:
+- The queues of patches, for both completed versions and in progress
+  versions can be found at:
 
-       https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git
+    https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git
 
- - The finalized and tagged releases of all stable kernels can be found
-   in separate branches per version at:
+- The finalized and tagged releases of all stable kernels can be found
+  in separate branches per version at:
 
-       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
+    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
 
- - The release candidate of all stable kernel versions can be found at:
+- The release candidate of all stable kernel versions can be found at:
 
-        https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/
+    https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/
 
-   .. warning::
-      The -stable-rc tree is a snapshot in time of the stable-queue tree and
-      will change frequently, hence will be rebased often. It should only be
-      used for testing purposes (e.g. to be consumed by CI systems).
+  .. warning::
+     The -stable-rc tree is a snapshot in time of the stable-queue tree and
+     will change frequently, hence will be rebased often. It should only be
+     used for testing purposes (e.g. to be consumed by CI systems).
 
 
 Review committee
 ----------------
 
- - This is made up of a number of kernel developers who have volunteered for
-   this task, and a few that haven't.
+- This is made up of a number of kernel developers who have volunteered for
+  this task, and a few that haven't.
index 5c4fa9f5d1cdb7a1691c95d09180be804b2f9e55..c9137710633a37d6c88c46191dbfc7e4fc4d32c6 100644 (file)
@@ -16,7 +16,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 Architecture   Level of support  Constraints
 =============  ================  ==============================================
 ``arm64``      Maintained        Little Endian only.
-``loongarch``  Maintained        -
+``loongarch``  Maintained        \-
 ``um``         Maintained        ``x86_64`` only.
 ``x86``        Maintained        ``x86_64`` only.
 =============  ================  ==============================================
index b73eb764a0017a6ccf312fc3da2bac9dafd74c2c..6d80d464ab6e7cfbf6509ca4dd739be69e9010ad 100644 (file)
@@ -81,7 +81,7 @@ A summary of the ``@optname`` entries is as follows::
                             destination addresses.
 
     SCTP_SENDMSG_CONNECT  - Initiate a connection that is generated by a
-                            sendmsg(2) or sctp_sendmsg(3) on a new asociation.
+                            sendmsg(2) or sctp_sendmsg(3) on a new association.
 
     SCTP_PRIMARY_ADDR     - Set local primary address.
 
index e989b9802f92abb81dd7eb4a1ccaccd7ac2435cf..f4d7e162d5e475bf01baafcd4dbbd9dfda9f5e6f 100644 (file)
@@ -42,6 +42,14 @@ safe.
          randomly generated and fused into each SoC at manufacturing time.
          Otherwise, a common fixed test key is used instead.
 
+     (4) DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
+
+         Rooted to a one-time programmable key (OTP) that is generally burnt
+         in the on-chip fuses and is accessible to the DCP encryption engine only.
+         DCP provides two keys that can be used as root of trust: the OTP key
+         and the UNIQUE key. Default is to use the UNIQUE key, but selecting
+         the OTP key can be done via a module parameter (dcp_use_otp_key).
+
   *  Execution isolation
 
      (1) TPM
@@ -57,6 +65,12 @@ safe.
 
          Fixed set of operations running in isolated execution environment.
 
+     (4) DCP
+
+         Fixed set of cryptographic operations running in isolated execution
+         environment. Only basic blob key encryption is executed there.
+         The actual key sealing/unsealing is done on main processor/kernel space.
+
   * Optional binding to platform integrity state
 
      (1) TPM
@@ -79,6 +93,11 @@ safe.
          Relies on the High Assurance Boot (HAB) mechanism of NXP SoCs
          for platform integrity.
 
+     (4) DCP
+
+         Relies on Secure/Trusted boot process (called HAB by vendor) for
+         platform integrity.
+
   *  Interfaces and APIs
 
      (1) TPM
@@ -94,6 +113,11 @@ safe.
 
          Interface is specific to silicon vendor.
 
+     (4) DCP
+
+         Vendor-specific API that is implemented as part of the DCP crypto driver in
+         ``drivers/crypto/mxs-dcp.c``.
+
   *  Threat model
 
      The strength and appropriateness of a particular trust source for a given
@@ -129,6 +153,13 @@ selected trust source:
      CAAM HWRNG, enable CRYPTO_DEV_FSL_CAAM_RNG_API and ensure the device
      is probed.
 
+  *  DCP (Data Co-Processor: crypto accelerator of various i.MX SoCs)
+
+     The DCP hardware device itself does not provide a dedicated RNG interface,
+     so the kernel default RNG is used. SoCs with DCP like the i.MX6ULL do have
+     a dedicated hardware RNG that is independent from DCP which can be enabled
+     to back the kernel RNG.
+
 Users may override this by specifying ``trusted.rng=kernel`` on the kernel
 command-line to override the used RNG with the kernel's random number pool.
 
@@ -231,6 +262,19 @@ Usage::
 CAAM-specific format.  The key length for new keys is always in bytes.
 Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
 
+Trusted Keys usage: DCP
+-----------------------
+
+Usage::
+
+    keyctl add trusted name "new keylen" ring
+    keyctl add trusted name "load hex_blob" ring
+    keyctl print keyid
+
+"keyctl print" returns an ASCII hex copy of the sealed key, which is in format
+specific to this DCP key-blob implementation.  The key length for new keys is
+always in bytes. Trusted Keys can be 32 - 128 bytes (256 - 1024 bits).
+
 Encrypted Keys usage
 --------------------
 
@@ -426,3 +470,12 @@ string length.
 privkey is the binary representation of TPM2B_PUBLIC excluding the
 initial TPM2B header which can be reconstructed from the ASN.1 octed
 string length.
+
+DCP Blob Format
+---------------
+
+.. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
+   :doc: dcp blob format
+
+.. kernel-doc:: security/keys/trusted-keys/trusted_dcp.c
+   :identifiers: struct dcp_blob_fmt
index ec66f2ed80c93a493cfeb4f229515af8315fd45b..3a2d41d2e64559f783d72c315ca666f3ca539f87 100644 (file)
@@ -4,7 +4,7 @@ Confidential Computing in Linux for x86 virtualization
 
 .. contents:: :local:
 
-By: Elena Reshetova <elena.reshetova@intel.com> and Carlos Bilbao <carlos.bilbao@amd.com>
+By: Elena Reshetova <elena.reshetova@intel.com> and Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 Motivation
 ==========
index fc40e9f23c8599b3dbf384afad78257540364c49..fa593d960040a95b5965042570ac874ace91c3cf 100644 (file)
@@ -5,6 +5,8 @@ Trusted Platform Module documentation
 .. toctree::
 
    tpm_event_log
+   tpm-security
+   tpm_tis
    tpm_vtpm_proxy
    xen-tpmfront
    tpm_ftpm_tee
diff --git a/Documentation/security/tpm/tpm-security.rst b/Documentation/security/tpm/tpm-security.rst
new file mode 100644 (file)
index 0000000..4f633f2
--- /dev/null
@@ -0,0 +1,216 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+TPM Security
+============
+
+The object of this document is to describe how we make the kernel's
+use of the TPM reasonably robust in the face of external snooping and
+packet alteration attacks (called passive and active interposer attack
+in the literature).  The current security document is for TPM 2.0.
+
+Introduction
+------------
+
+The TPM is usually a discrete chip attached to a PC via some type of
+low bandwidth bus.  There are exceptions to this such as the Intel
+PTT, which is a software TPM running inside a software environment
+close to the CPU, which are subject to different attacks, but right at
+the moment, most hardened security environments require a discrete
+hardware TPM, which is the use case discussed here.
+
+Snooping and Alteration Attacks against the bus
+-----------------------------------------------
+
+The current state of the art for snooping the `TPM Genie`_ hardware
+interposer which is a simple external device that can be installed in
+a couple of seconds on any system or laptop.  Recently attacks were
+successfully demonstrated against the `Windows Bitlocker TPM`_ system.
+Most recently the same `attack against TPM based Linux disk
+encryption`_ schemes.  The next phase of research seems to be hacking
+existing devices on the bus to act as interposers, so the fact that
+the attacker requires physical access for a few seconds might
+evaporate.  However, the goal of this document is to protect TPM
+secrets and integrity as far as we are able in this environment and to
+try to insure that if we can't prevent the attack then at least we can
+detect it.
+
+Unfortunately, most of the TPM functionality, including the hardware
+reset capability can be controlled by an attacker who has access to
+the bus, so we'll discuss some of the disruption possibilities below.
+
+Measurement (PCR) Integrity
+---------------------------
+
+Since the attacker can send their own commands to the TPM, they can
+send arbitrary PCR extends and thus disrupt the measurement system,
+which would be an annoying denial of service attack.  However, there
+are two, more serious, classes of attack aimed at entities sealed to
+trust measurements.
+
+1. The attacker could intercept all PCR extends coming from the system
+   and completely substitute their own values, producing a replay of
+   an untampered state that would cause PCR measurements to attest to
+   a trusted state and release secrets
+
+2. At some point in time the attacker could reset the TPM, clearing
+   the PCRs and then send down their own measurements which would
+   effectively overwrite the boot time measurements the TPM has
+   already done.
+
+The first can be thwarted by always doing HMAC protection of the PCR
+extend and read command meaning measurement values cannot be
+substituted without producing a detectable HMAC failure in the
+response.  However, the second can only really be detected by relying
+on some sort of mechanism for protection which would change over TPM
+reset.
+
+Secrets Guarding
+----------------
+
+Certain information passing in and out of the TPM, such as key sealing
+and private key import and random number generation, is vulnerable to
+interception which HMAC protection alone cannot protect against, so
+for these types of command we must also employ request and response
+encryption to prevent the loss of secret information.
+
+Establishing Initial Trust with the TPM
+---------------------------------------
+
+In order to provide security from the beginning, an initial shared or
+asymmetric secret must be established which must also be unknown to
+the attacker.  The most obvious avenues for this are the endorsement
+and storage seeds, which can be used to derive asymmetric keys.
+However, using these keys is difficult because the only way to pass
+them into the kernel would be on the command line, which requires
+extensive support in the boot system, and there's no guarantee that
+either hierarchy would not have some type of authorization.
+
+The mechanism chosen for the Linux Kernel is to derive the primary
+elliptic curve key from the null seed using the standard storage seed
+parameters.  The null seed has two advantages: firstly the hierarchy
+physically cannot have an authorization, so we are always able to use
+it and secondly, the null seed changes across TPM resets, meaning if
+we establish trust on the null seed at start of day, all sessions
+salted with the derived key will fail if the TPM is reset and the seed
+changes.
+
+Obviously using the null seed without any other prior shared secrets,
+we have to create and read the initial public key which could, of
+course, be intercepted and substituted by the bus interposer.
+However, the TPM has a key certification mechanism (using the EK
+endorsement certificate, creating an attestation identity key and
+certifying the null seed primary with that key) which is too complex
+to run within the kernel, so we keep a copy of the null primary key
+name, which is what is exported via sysfs so user-space can run the
+full certification when it boots.  The definitive guarantee here is
+that if the null primary key certifies correctly, you know all your
+TPM transactions since start of day were secure and if it doesn't, you
+know there's an interposer on your system (and that any secret used
+during boot may have been leaked).
+
+Stacking Trust
+--------------
+
+In the current null primary scenario, the TPM must be completely
+cleared before handing it on to the next consumer.  However the kernel
+hands to user-space the name of the derived null seed key which can
+then be verified by certification in user-space.  Therefore, this chain
+of name handoff can be used between the various boot components as
+well (via an unspecified mechanism).  For instance, grub could use the
+null seed scheme for security and hand the name off to the kernel in
+the boot area.  The kernel could make its own derivation of the key
+and the name and know definitively that if they differ from the handed
+off version that tampering has occurred.  Thus it becomes possible to
+chain arbitrary boot components together (UEFI to grub to kernel) via
+the name handoff provided each successive component knows how to
+collect the name and verifies it against its derived key.
+
+Session Properties
+------------------
+
+All TPM commands the kernel uses allow sessions.  HMAC sessions may be
+used to check the integrity of requests and responses and decrypt and
+encrypt flags may be used to shield parameters and responses.  The
+HMAC and encryption keys are usually derived from the shared
+authorization secret, but for a lot of kernel operations that is well
+known (and usually empty).  Thus, every HMAC session used by the
+kernel must be created using the null primary key as the salt key
+which thus provides a cryptographic input into the session key
+derivation.  Thus, the kernel creates the null primary key once (as a
+volatile TPM handle) and keeps it around in a saved context stored in
+tpm_chip for every in-kernel use of the TPM.  Currently, because of a
+lack of de-gapping in the in-kernel resource manager, the session must
+be created and destroyed for each operation, but, in future, a single
+session may also be reused for the in-kernel HMAC, encryption and
+decryption sessions.
+
+Protection Types
+----------------
+
+For every in-kernel operation we use null primary salted HMAC to
+protect the integrity.  Additionally, we use parameter encryption to
+protect key sealing and parameter decryption to protect key unsealing
+and random number generation.
+
+Null Primary Key Certification in Userspace
+===========================================
+
+Every TPM comes shipped with a couple of X.509 certificates for the
+primary endorsement key.  This document assumes that the Elliptic
+Curve version of the certificate exists at 01C00002, but will work
+equally well with the RSA certificate (at 01C00001).
+
+The first step in the certification is primary creation using the
+template from the `TCG EK Credential Profile`_ which allows comparison
+of the generated primary key against the one in the certificate (the
+public key must match).  Note that generation of the EK primary
+requires the EK hierarchy password, but a pre-generated version of the
+EC primary should exist at 81010002 and a TPM2_ReadPublic() may be
+performed on this without needing the key authority.  Next, the
+certificate itself must be verified to chain back to the manufacturer
+root (which should be published on the manufacturer website).  Once
+this is done, an attestation key (AK) is generated within the TPM and
+it's name and the EK public key can be used to encrypt a secret using
+TPM2_MakeCredential.  The TPM then runs TPM2_ActivateCredential which
+will only recover the secret if the binding between the TPM, the EK
+and the AK is true. the generated AK may now be used to run a
+certification of the null primary key whose name the kernel has
+exported.  Since TPM2_MakeCredential/ActivateCredential are somewhat
+complicated, a more simplified process involving an externally
+generated private key is described below.
+
+This process is a simplified abbreviation of the usual privacy CA
+based attestation process.  The assumption here is that the
+attestation is done by the TPM owner who thus has access to only the
+owner hierarchy.  The owner creates an external public/private key
+pair (assume elliptic curve in this case) and wraps the private key
+for import using an inner wrapping process and parented to the EC
+derived storage primary.  The TPM2_Import() is done using a parameter
+decryption HMAC session salted to the EK primary (which also does not
+require the EK key authority) meaning that the inner wrapping key is
+the encrypted parameter and thus the TPM will not be able to perform
+the import unless is possesses the certified EK so if the command
+succeeds and the HMAC verifies on return we know we have a loadable
+copy of the private key only for the certified TPM.  This key is now
+loaded into the TPM and the Storage primary flushed (to free up space
+for the null key generation).
+
+The null EC primary is now generated using the Storage profile
+outlined in the `TCG TPM v2.0 Provisioning Guidance`_; the name of
+this key (the hash of the public area) is computed and compared to the
+null seed name presented by the kernel in
+/sys/class/tpm/tpm0/null_name.  If the names do not match, the TPM is
+compromised.  If the names match, the user performs a TPM2_Certify()
+using the null primary as the object handle and the loaded private key
+as the sign handle and providing randomized qualifying data.  The
+signature of the returned certifyInfo is verified against the public
+part of the loaded private key and the qualifying data checked to
+prevent replay.  If all of these tests pass, the user is now assured
+that TPM integrity and privacy was preserved across the entire boot
+sequence of this kernel.
+
+.. _TPM Genie: https://www.nccgroup.trust/globalassets/about-us/us/documents/tpm-genie.pdf
+.. _Windows Bitlocker TPM: https://dolosgroup.io/blog/2021/7/9/from-stolen-laptop-to-inside-the-company-network
+.. _attack against TPM based Linux disk encryption: https://www.secura.com/blog/tpm-sniffing-attacks-against-non-bitlocker-targets
+.. _TCG EK Credential Profile: https://trustedcomputinggroup.org/resource/tcg-ek-credential-profile-for-tpm-family-2-0/
+.. _TCG TPM v2.0 Provisioning Guidance: https://trustedcomputinggroup.org/resource/tcg-tpm-v2-0-provisioning-guidance/
diff --git a/Documentation/security/tpm/tpm_tis.rst b/Documentation/security/tpm/tpm_tis.rst
new file mode 100644 (file)
index 0000000..b9637f2
--- /dev/null
@@ -0,0 +1,46 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=========================
+TPM FIFO interface driver
+=========================
+
+TCG PTP Specification defines two interface types: FIFO and CRB. The former is
+based on sequenced read and write operations,  and the latter is based on a
+buffer containing the full command or response.
+
+FIFO (First-In-First-Out) interface is used by the tpm_tis_core dependent
+drivers. Originally Linux had only a driver called tpm_tis, which covered
+memory mapped (aka MMIO) interface but it was later on extended to cover other
+physical interfaces supported by the TCG standard.
+
+For historical reasons above the original MMIO driver is called tpm_tis and the
+framework for FIFO drivers is named as tpm_tis_core. The postfix "tis" in
+tpm_tis comes from the TPM Interface Specification, which is the hardware
+interface specification for TPM 1.x chips.
+
+Communication is based on a 20 KiB buffer shared by the TPM chip through a
+hardware bus or memory map, depending on the physical wiring. The buffer is
+further split into five equal-size 4 KiB buffers, which provide equivalent
+sets of registers for communication between the CPU and TPM. These
+communication endpoints are called localities in the TCG terminology.
+
+When the kernel wants to send commands to the TPM chip, it first reserves
+locality 0 by setting the requestUse bit in the TPM_ACCESS register. The bit is
+cleared by the chip when the access is granted. Once it completes its
+communication, the kernel writes the TPM_ACCESS.activeLocality bit. This
+informs the chip that the locality has been relinquished.
+
+Pending localities are served in order by the chip in descending order, one at
+a time:
+
+- Locality 0 has the lowest priority.
+- Locality 5 has the highest priority.
+
+Further information on the purpose and meaning of the localities can be found
+in section 3.2 of the TCG PC Client Platform TPM Profile Specification.
+
+References
+==========
+
+TCG PC Client Platform TPM Profile (PTP) Specification
+https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
index abe7680883771d49b72d7f382b45ca3e2514df7f..6387624423363d45ec63c36cbe83754bf7b10d21 100755 (executable)
@@ -97,7 +97,6 @@ class KernelInclude(Include):
         # HINT: this is the only line I had to change / commented out:
         #path = utils.relative_path(None, path)
 
-        path = nodes.reprunicode(path)
         encoding = self.options.get(
             'encoding', self.state.document.settings.input_encoding)
         e_handler=self.state.document.settings.input_encoding_error_handler
index 3092df051c952e82c62f433b731593d25fcc735e..d479cfa73658ade9036b8634ec4c078c4dfe5753 100644 (file)
            due to the lack of suitable font families and/or the texlive-xecjk
            package.
 
-           If you want them, please install ``Noto Sans CJK'' font families
-           along with the texlive-xecjk package by following instructions from
+           If you want them, please install non-variable ``Noto Sans CJK''
+           font families along with the texlive-xecjk package by following
+           instructions from
            \sphinxcode{./scripts/sphinx-pre-install}.
-           Having optional ``Noto Serif CJK'' font families will improve
-           the looks of those translations.
+           Having optional non-variable ``Noto Serif CJK'' font families will
+           improve the looks of those translations.
        \end{sphinxadmonition}}
     \newcommand{\kerneldocEndSC}{}
     \newcommand{\kerneldocBeginTC}[1]{}
index a23bd08847e5a24ea9b8b3245ad62c6a017cbe91..4be6e69d7837c86519d5b6ac855e8bfa16af7655 100644 (file)
@@ -10,6 +10,7 @@ TEE Subsystem
    tee
    op-tee
    amd-tee
+   ts-tee
 
 .. only::  subproject and html
 
diff --git a/Documentation/tee/ts-tee.rst b/Documentation/tee/ts-tee.rst
new file mode 100644 (file)
index 0000000..843e344
--- /dev/null
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================================
+TS-TEE (Trusted Services project)
+=================================
+
+This driver provides access to secure services implemented by Trusted Services.
+
+Trusted Services [1] is a TrustedFirmware.org project that provides a framework
+for developing and deploying device Root of Trust services in FF-A [2] S-EL0
+Secure Partitions. The project hosts the reference implementation of the Arm
+Platform Security Architecture [3] for Arm A-profile devices.
+
+The FF-A Secure Partitions (SP) are accessible through the FF-A driver [4] which
+provides the low level communication for this driver. On top of that the Trusted
+Services RPC protocol is used [5]. To use the driver from user space a reference
+implementation is provided at [6], which is part of the Trusted Services client
+library called libts [7].
+
+All Trusted Services (TS) SPs have the same FF-A UUID; it identifies the TS RPC
+protocol. A TS SP can host one or more services (e.g. PSA Crypto, PSA ITS, etc).
+A service is identified by its service UUID; the same type of service cannot be
+present twice in the same SP. During SP boot each service in the SP is assigned
+an "interface ID". This is just a short ID to simplify message addressing.
+
+The generic TEE design is to share memory at once with the Trusted OS, which can
+then be reused to communicate with multiple applications running on the Trusted
+OS. However, in case of FF-A, memory sharing works on an endpoint level, i.e.
+memory is shared with a specific SP. User space has to be able to separately
+share memory with each SP based on its endpoint ID; therefore a separate TEE
+device is registered for each discovered TS SP. Opening the SP corresponds to
+opening the TEE device and creating a TEE context. A TS SP hosts one or more
+services. Opening a service corresponds to opening a session in the given
+tee_context.
+
+Overview of a system with Trusted Services components::
+
+   User space                  Kernel space                   Secure world
+   ~~~~~~~~~~                  ~~~~~~~~~~~~                   ~~~~~~~~~~~~
+   +--------+                                               +-------------+
+   | Client |                                               | Trusted     |
+   +--------+                                               | Services SP |
+      /\                                                    +-------------+
+      ||                                                          /\
+      ||                                                          ||
+      ||                                                          ||
+      \/                                                          \/
+   +-------+                +----------+--------+           +-------------+
+   | libts |                |  TEE     | TS-TEE |           |  FF-A SPMC  |
+   |       |                |  subsys  | driver |           |   + SPMD    |
+   +-------+----------------+----+-----+--------+-----------+-------------+
+   |      Generic TEE API        |     |  FF-A  |     TS RPC protocol     |
+   |      IOCTL (TEE_IOC_*)      |     | driver |        over FF-A        |
+   +-----------------------------+     +--------+-------------------------+
+
+References
+==========
+
+[1] https://www.trustedfirmware.org/projects/trusted-services/
+
+[2] https://developer.arm.com/documentation/den0077/
+
+[3] https://www.arm.com/architecture/security-features/platform-security
+
+[4] drivers/firmware/arm_ffa/
+
+[5] https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
+
+[6] https://git.trustedfirmware.org/TS/trusted-services.git/tree/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c?h=v1.0.0
+
+[7] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/libts/arm-linux/CMakeLists.txt?h=v1.0.0
index f8786be15183c15879a188f61fa36bceda99c6e9..7fe8ef9718d8e357567671295a3cc4dc1c97751a 100644 (file)
@@ -129,11 +129,8 @@ adaptive-tick CPUs:  At least one non-adaptive-tick CPU must remain
 online to handle timekeeping tasks in order to ensure that system
 calls like gettimeofday() returns accurate values on adaptive-tick CPUs.
 (This is not an issue for CONFIG_NO_HZ_IDLE=y because there are no running
-user processes to observe slight drifts in clock rate.)  Therefore, the
-boot CPU is prohibited from entering adaptive-ticks mode.  Specifying a
-"nohz_full=" mask that includes the boot CPU will result in a boot-time
-error message, and the boot CPU will be removed from the mask.  Note that
-this means that your system must have at least two CPUs in order for
+user processes to observe slight drifts in clock rate.) Note that this
+means that your system must have at least two CPUs in order for
 CONFIG_NO_HZ_FULL=y to do anything for you.
 
 Finally, adaptive-ticks CPUs must have their RCU callbacks offloaded.
index 0f187e3796e4b40e15f3036be2642511d6c9af53..b4c2ca3d02c162513b9c67e5c1909e8f1848b13b 100644 (file)
@@ -74,7 +74,7 @@ Function arguments at exit
 --------------------------
 Function arguments can be accessed at exit probe using $arg<N> fetcharg. This
 is useful to record the function parameter and return value at once, and
-trace the difference of structure fields (for debuging a function whether it
+trace the difference of structure fields (for debugging a function whether it
 correctly updates the given data structure or not)
 See the :ref:`sample<fprobetrace_exit_args_sample>` below for how it works.
 
@@ -248,4 +248,4 @@ mode. You can trace that changes with return probe.
              cat-143     [007] ...1.  1945.720616: vfs_open__entry: (vfs_open+0x4/0x40) mode=0x1 inode=0x0
              cat-143     [007] ...1.  1945.728263: vfs_open__exit: (do_open+0x274/0x3d0 <- vfs_open) mode=0xa800d inode=0xffff888004ada8d8
 
-You can see the `file::f_mode` and `file::f_inode` are upated in `vfs_open()`.
+You can see the `file::f_mode` and `file::f_inode` are updated in `vfs_open()`.
index 7e7b8ec1793483c4843b2281475d4cf9e300b021..5aba74872ba77df92711ef38211a7bd76a1797e3 100644 (file)
@@ -1968,7 +1968,7 @@ wakeup
 One common case that people are interested in tracing is the
 time it takes for a task that is woken to actually wake up.
 Now for non Real-Time tasks, this can be arbitrary. But tracing
-it none the less can be interesting. 
+it nonetheless can be interesting. 
 
 Without function tracing::
 
index e1636e579c9ccdfec96545a25502a6ef60de6383..5e606730cec633cea4dd3877727e352a25a5fc02 100644 (file)
@@ -322,6 +322,7 @@ architectures:
 - s390
 - parisc
 - loongarch
+- riscv
 
 Configuring Kprobes
 ===================
index a49662ccd53cdac5eb08adc778c9c98cb826c4eb..69cb7776ae9905e168c09d2fd35920220f5152f2 100644 (file)
@@ -74,7 +74,7 @@ Function arguments at kretprobe
 -------------------------------
 Function arguments can be accessed at kretprobe using $arg<N> fetcharg. This
 is useful to record the function parameter and return value at once, and
-trace the difference of structure fields (for debuging a function whether it
+trace the difference of structure fields (for debugging a function whether it
 correctly updates the given data structure or not).
 See the :ref:`sample<fprobetrace_exit_args_sample>` in fprobe event for how
 it works.
index 0cb8d9ca3d608d771387b11fd80c78220d99cd0a..decabcc77b567c9af7f0eace310f9efa57b063ca 100644 (file)
@@ -27,7 +27,7 @@ the tracepoint site).
 
 You can put tracepoints at important locations in the code. They are
 lightweight hooks that can pass an arbitrary number of parameters,
-which prototypes are described in a tracepoint declaration placed in a
+whose prototypes are described in a tracepoint declaration placed in a
 header file.
 
 They can be used for tracing and performance accounting.
index 5cece223b46ba08d44235ff1d2b3891378a99603..74057d203539e07c85ef5b7e0b237d1ac737bbf5 100644 (file)
@@ -180,9 +180,9 @@ Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome
      se provate a formattare bene il vostro testo come nel seguente esempio::
 
        * Return:
-       * 0 - OK
-       * -EINVAL - invalid argument
-       * -ENOMEM - out of memory
+       * %0 - OK
+       * %-EINVAL - invalid argument
+       * %-ENOMEM - out of memory
 
      le righe verranno unite e il risultato sarà::
 
@@ -192,8 +192,8 @@ Il valore di ritorno, se c'è, viene descritto in una sezione dedicata di nome
      utilizzare una lista ReST, ad esempio::
 
       * Return:
-      * *            - OK to runtime suspend the device
-      * * -EBUSY       - Device should not be runtime suspended
+      * * %0           - OK to runtime suspend the device
+      * * %-EBUSY      - Device should not be runtime suspended
 
   #) Se il vostro testo ha delle righe che iniziano con una frase seguita dai
      due punti, allora ognuna di queste frasi verrà considerata come il nome
index 70ccd23b2cdeba883749a6d3aacb7cd871c9366b..9220f65e30d1f06eef28b0e87b72479a3c0e15c1 100644 (file)
@@ -132,4 +132,4 @@ Documentazione varia
 
 Ci sono documenti che sono difficili da inserire nell'attuale organizzazione
 della documentazione; altri hanno bisogno di essere migliorati e/o convertiti
-nel formato *ReStructured Text*; altri sono semplicamente troppo vecchi.
+nel formato *reStructuredText*; altri sono semplicamente troppo vecchi.
index 25cd00351c03003fe5e947b99bd6eeff55b6df6d..0a62c0f33faf9dd1691b3c564e0f95c92df6d22a 100644 (file)
@@ -462,9 +462,12 @@ linux-kernel:
   di far domande.  Molti sviluppatori possono divenire impazienti con le
   persone che chiaramente non hanno svolto i propri compiti a casa.
 
-- Evitate il *top-posting* (cioè la pratica di mettere la vostra risposta sopra
-  alla frase alla quale state rispondendo).  Ciò renderebbe la vostra risposta
-  difficile da leggere e genera scarsa impressione.
+- Rispondete sotto alla porzione di righe citate, così da dare un contesto alle
+  vostre risposte, e quindi renderle più leggibili (in altre parole, evitate di
+  rispondere in cima, ovvero prima del testo citato). Per maggiori dettagli
+  leggete :ref:`Documentation/translations/it_IT/process/submitting-patches.rst
+  <it_interleaved_replies>`.
+
 
 - Chiedete nella lista di discussione corretta.  Linux-kernel può essere un
   punto di incontro generale, ma non è il miglior posto dove trovare
index 54fd255b77d02c61a26350b681607823bf0dfc4a..ec874a8dfb9d903ec81a87ffca028dea925993a0 100644 (file)
@@ -72,6 +72,10 @@ compiti del genere.  Consultate il file
 :ref:`Documentation/translations/it_IT/process/clang-format.rst <clangformat>`
 per maggiori dettagli
 
+Se utilizzate un programma compatibile con EditorConfig, allora alcune
+configurazioni basilari come l'indentazione e la fine delle righe verranno
+applicate automaticamente. Per maggiori informazioni consultate la pagina:
+https://editorconfig.org/
 
 Livelli di astrazione
 *********************
index dffd813a09103dca975ee1307ec051eaad35b45a..a83fcfe18024f90c72f7745b3e7caf78e785c4e6 100644 (file)
@@ -160,6 +160,8 @@ preparerà una richiesta nel modo in cui gli altri sviluppatori se l'aspettano,
 e verificherà che vi siate ricordati di pubblicare quelle patch su un
 server pubblico.
 
+.. _development_advancedtopics_reviews_it:
+
 Revisionare le patch
 --------------------
 
@@ -180,6 +182,13 @@ i commenti come domande e non come critiche.  Chiedere "Come viene rilasciato
 il *lock* in questo percorso?" funziona sempre molto meglio che
 "qui la sincronizzazione è sbagliata".
 
+In caso di disaccordi, può essere utile chiedere una terza opinione. Se dopo
+pochi scambi la discussione raggiunge un punto morto, allora chiedete ai
+manutentori o altri revisori di partecipare esprimendo la loro opinione. Spesso
+vige un silenzio assenso per cui gli altri revisori non intervengono se non gli
+viene richiesto esplicitamente. L'opinione di più persone avrà sicuramente un
+peso maggiore.
+
 Diversi sviluppatori revisioneranno il codice con diversi punti di vista.
 Alcuni potrebbero concentrarsi principalmente sullo stile del codice e se
 alcune linee hanno degli spazio bianchi di troppo.  Altri si chiederanno
@@ -189,3 +198,13 @@ l'uso eccessivo di *stack*, problemi di sicurezza, duplicazione del codice
 in altri contesti, documentazione, effetti negativi sulle prestazioni, cambi
 all'ABI dello spazio utente, eccetera.  Qualunque tipo di revisione è ben
 accetta e di valore, se porta ad avere un codice migliore nel kernel.
+
+Non esistono requisiti particolarmente stringenti per l'uso di etichette come
+``Reviewd-by``. Tuttavia, perché la revisione sia efficace ci si aspetta un
+qualche tipo di messaggio che dica "ho verificato A, B e C nel codice che è
+appena stato inviato e mi sembra tutto in ordine". Inoltre, questo permette ai
+manutentori di prendere conoscenza circa una revisione avvenuta per davvero.
+
+Per finire, la revisione delle patch può diventare un processo negativo, troppo
+focalizzato sulla ricerca dei problemi. Provate a fare qualche complimento di
+tanto in tanto, specialmente con i nuovi arrivati.
index f37c53f8b5242638aa18a70d54028428c3f02905..ade695a7de19b327105dbafbf8a2059e3e5c8af3 100644 (file)
@@ -34,13 +34,15 @@ PC Card, per esempio, probabilmente non dovreste preoccuparvi di pcmciautils.
 ====================== =================  ========================================
 GNU C                  5.1                gcc --version
 Clang/LLVM (optional)  11.0.0             clang --version
+Rust (opzionale)       1.74.1             rustc --version
+bindgen (opzionale)    0.65.1             bindgen --version
 GNU make               3.81               make --version
 bash                   4.2                bash --version
 binutils               2.25               ld -v
 flex                   2.5.35             flex --version
 bison                  2.0                bison --version
 pahole                 1.16               pahole --version
-util-linux             2.10o              fdformat --version
+util-linux             2.10o              mount --version
 kmod                   13                 depmod -V
 e2fsprogs              1.41.4             e2fsck -V
 jfsutils               1.1.3              fsck.jfs -V
@@ -59,8 +61,10 @@ mcelog                 0.6                mcelog --version
 iptables               1.4.2              iptables -V
 openssl & libcrypto    1.0.0              openssl version
 bc                     1.06.95            bc --version
-Sphinx\ [#f1]_         1.7                sphinx-build --version
+Sphinx\ [#f1]_         2.4.4              sphinx-build --version
 cpio                   any                cpio --version
+GNU tar                1.28               tar --version
+gtags (opzionale)      6.6.5              gtags --version
 ====================== =================  ========================================
 
 .. [#f1] Sphinx è necessario solo per produrre la documentazione del Kernel
@@ -151,6 +155,18 @@ Se la firma dei moduli è abilitata, allora vi servirà openssl per compilare il
 kernel 3.7 e successivi.  Vi serviranno anche i pacchetti di sviluppo di
 openssl per compilare il kernel 4.3 o successivi.
 
+Tar
+---
+
+GNU Tar è necessario per accedere ai file d'intestazione del kernel usando sysfs
+(CONFIG_IKHEADERS)
+
+gtags / GNU GLOBAL (opzionale)
+------------------------------
+
+Il programma GNU GLOBAL versione 6.6.5, o successiva, è necessario quando si
+vuole eseguire ``make gtags`` e generare i relativi indici. Internamente si fa
+uso del parametro gtags ``-C (--directory)`` che compare in questa versione.
 
 Strumenti di sistema
 ********************
@@ -434,7 +450,7 @@ E2fsprogs
 JFSutils
 --------
 
-- <http://jfs.sourceforge.net/>
+- <https://jfs.sourceforge.net/>
 
 Reiserfsprogs
 -------------
@@ -455,7 +471,7 @@ Pcmciautils
 Quota-tools
 -----------
 
-- <http://sourceforge.net/projects/linuxquota/>
+- <https://sourceforge.net/projects/linuxquota/>
 
 
 Microcodice Intel P6
@@ -476,7 +492,7 @@ FUSE
 mcelog
 ------
 
-- <http://www.mcelog.org/>
+- <https://www.mcelog.org/>
 
 cpio
 ----
@@ -497,7 +513,8 @@ PPP
 NFS-utils
 ---------
 
-- <http://sourceforge.net/project/showfiles.php?group_id=14>
+- <https://sourceforge.net/project/showfiles.php?group_id=14>
+- <https://nfs.sourceforge.net/>
 
 Iptables
 --------
@@ -512,12 +529,7 @@ Ip-route2
 OProfile
 --------
 
-- <http://oprofile.sf.net/download/>
-
-NFS-Utils
----------
-
-- <http://nfs.sourceforge.net/>
+- <https://oprofile.sf.net/download/>
 
 Documentazione del kernel
 *************************
index 284a75ac19f8e1c8f455a9f7c661db4483e04688..a4b9f44081dae8c2ce8fea8a4f555e9acba5ffb2 100644 (file)
@@ -214,7 +214,7 @@ Non usate inutilmente le graffe dove una singola espressione è sufficiente.
 
 e
 
-.. code-block:: none
+.. code-block:: c
 
        if (condition)
                do_this();
@@ -652,7 +652,7 @@ Quindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più
 sensati.  Per fare quest'ultima cosa, potete appiccicare il codice che
 segue nel vostro file .emacs:
 
-.. code-block:: none
+.. code-block:: elisp
 
   (defun c-lineup-arglist-tabs-only (ignored)
     "Line up argument lists by tabs, not spaces"
@@ -728,6 +728,10 @@ il testo e altre cose simili.
 Per maggiori dettagli, consultate il file
 :ref:`Documentation/translations/it_IT/process/clang-format.rst <it_clangformat>`.
 
+Se utilizzate un programma compatibile con EditorConfig, allora alcune
+configurazioni basilari come l'indentazione e la fine delle righe verranno
+applicate automaticamente. Per maggiori informazioni consultate la pagina:
+https://editorconfig.org/
 
 10) File di configurazione Kconfig
 ----------------------------------
@@ -898,7 +902,9 @@ usare per assicurarvi che i messaggi vengano associati correttamente ai
 dispositivi e ai driver, e che siano etichettati correttamente:  dev_err(),
 dev_warn(), dev_info(), e così via.  Per messaggi che non sono associati ad
 alcun dispositivo, <linux/printk.h> definisce pr_info(), pr_warn(), pr_err(),
-eccetera.
+eccetera. Quando tutto funziona correttamente, non dovrebbero esserci stampe,
+per cui preferite dev_dbg/pr_debug a meno che non sia qualcosa di sbagliato
+da segnalare.
 
 Tirar fuori un buon messaggio di debug può essere una vera sfida; e quando
 l'avete può essere d'enorme aiuto per risolvere problemi da remoto.
index ba0ed7dc154c95e0e973cb51cc36b95e786079a8..d4ab76e9be49500d95e8510a74042d6c87037ee0 100644 (file)
@@ -86,7 +86,7 @@ da kcalloc().
 Se questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
 le funzioni del tipo *saturate-on-overflow*::
 
-       bar = vmalloc(array_size(count, size));
+       bar = dma_alloc_coherent(dev, array_size(count, size), &dma, GFP_KERNEL);
 
 Un altro tipico caso da evitare è quello di calcolare la dimensione di una
 struttura seguita da un vettore di altre strutture, come nel seguente caso::
index 052f1b3610cb1ff95a271932da53493c193ce39e..090941a0a898e71aa206ea497c716d20c38db4d7 100644 (file)
@@ -85,8 +85,8 @@ relativi file di documentatione che spiegano come usarele.
 Quando un cambiamento del kernel genera anche un cambiamento nell'interfaccia
 con lo spazio utente, è raccomandabile che inviate una notifica o una
 correzione alle pagine *man* spiegando tale modifica agli amministratori di
-queste pagine all'indirizzo mtk.manpages@gmail.com, aggiungendo
-in CC la lista linux-api@vger.kernel.org.
+queste pagine all'indirizzo alx@kernel.org, aggiungendo in CC la
+lista linux-api@vger.kernel.org.
 
 Di seguito una lista di file che sono presenti nei sorgente del kernel e che
 è richiesto che voi leggiate:
@@ -144,7 +144,7 @@ Di seguito una lista di file che sono presenti nei sorgente del kernel e che
     dello sviluppo di Linux ed è molto importante per le persone che arrivano
     da esperienze con altri Sistemi Operativi.
 
-  :ref:`Documentation/translations/it_IT/admin-guide/security-bugs.rst <it_securitybugs>`
+  :ref:`Documentation/translations/it_IT/process/security-bugs.rst <it_securitybugs>`
     Se ritenete di aver trovato un problema di sicurezza nel kernel Linux,
     seguite i passaggi scritti in questo documento per notificarlo agli
     sviluppatori del kernel, ed aiutare la risoluzione del problema.
index cd7977905fb880acc63fb7f8cc128d9929ef30f5..73c643dcc541a42ee75bc87859cd6b5b380c3354 100644 (file)
@@ -21,19 +21,75 @@ l'accettazione delle vostre modifiche con il minimo sforzo.
 
 Di seguito le guide che ogni sviluppatore dovrebbe leggere.
 
+Introduzione al funzionamento dello sviluppo del kernel
+-------------------------------------------------------
+
+Innanzitutto, leggete questi documenti che vi aiuteranno ad entrare nella
+comunità del kernel.
+
 .. toctree::
    :maxdepth: 1
 
    howto
-   code-of-conduct
    development-process
    submitting-patches
+   submit-checklist
+
+Strumenti e guide tecniche per gli sviluppatori del kernel
+----------------------------------------------------------
+
+Quella che segue è una raccolta di documenti che uno sviluppatore del kernel
+Linux dovrebbe conoscere.
+
+.. toctree::
+   :maxdepth: 1
+
+   changes
    programming-language
    coding-style
    maintainer-pgp-guide
    email-clients
+   applying-patches
+   adding-syscalls
+   volatile-considered-harmful
+   botching-up-ioctls
+
+Politiche e dichiarazioni degli sviluppatori
+--------------------------------------------
+
+Quelle che seguono rappresentano le regole che cerchiamo di seguire all'interno
+della comunità del kernel (e oltre).
+
+.. toctree::
+   :maxdepth: 1
+
+   code-of-conduct
    kernel-enforcement-statement
    kernel-driver-statement
+   stable-api-nonsense
+   stable-kernel-rules
+   management-style
+
+Gestire i bachi
+---------------
+
+I bachi sono parte della nostra vita; dunque è importante che vengano trattati
+con riguardo. I documenti che seguono descrivono le nostre politiche riguardo al
+trattamento di alcune classi particolari di bachi: le regressioni e i problemi
+di sicurezza.
+
+Informazioni per i manutentori
+------------------------------
+
+Come trovare le persone che accetteranno le vostre modifiche.
+
+.. toctree::
+   :maxdepth: 1
+
+   maintainers
+
+Altri documenti
+---------------
 
 Poi ci sono altre guide sulla comunità che sono di interesse per molti
 degli sviluppatori:
@@ -41,13 +97,7 @@ degli sviluppatori:
 .. toctree::
    :maxdepth: 1
 
-   changes
-   stable-api-nonsense
-   management-style
-   stable-kernel-rules
-   submit-checklist
    kernel-docs
-   maintainers
 
 Ed infine, qui ci sono alcune guide più tecniche che son state messe qua solo
 perché non si è trovato un posto migliore.
@@ -55,11 +105,7 @@ perché non si è trovato un posto migliore.
 .. toctree::
    :maxdepth: 1
 
-   applying-patches
-   adding-syscalls
    magic-number
-   volatile-considered-harmful
-   botching-up-ioctls
    clang-format
    ../riscv/patch-acceptance
 
index 248bf1e4b171b49631d09953713531e3b9423b34..a2577a806a1820bbb5850b052ae4ad43efbce4b0 100644 (file)
@@ -44,7 +44,7 @@ Procedura per sottomettere patch per i sorgenti -stable
 .. note::
   Una patch di sicurezza non dovrebbe essere gestita (solamente) dal processo
   di revisione -stable, ma dovrebbe seguire le procedure descritte in
-  :ref:`Documentation/translations/it_IT/admin-guide/security-bugs.rst <it_securitybugs>`.
+  :ref:`Documentation/translations/it_IT/process/security-bugs.rst <it_securitybugs>`.
 
 Per tutte le altre sottomissioni, scegliere una delle seguenti procedure
 ------------------------------------------------------------------------
index f91c8092844ff19e1c3d442263b331beed43a8b9..4c6a276bdc0894815acc9dabad7bbe1d8cb28d40 100644 (file)
@@ -349,6 +349,33 @@ Leggete Documentation/translations/it_IT/process/email-clients.rst per
 le raccomandazioni sui programmi di posta elettronica e l'etichetta da usare
 sulle liste di discussione.
 
+.. _it_interleaved_replies:
+
+Rispondere alle email in riga e riducendo la citazioni
+------------------------------------------------------
+
+Nelle discussioni riguardo allo sviluppo del kernel viene fortemente scoraggiato
+l'uso di risposte in cima ai messaggi di posta elettronica. Rispondere in riga
+rende le conversazioni molto più scorrevoli. Maggiori dettagli possono essere
+trovati qui: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
+
+Come spesso citato nelle liste di discussione::
+
+  R: http://en.wikipedia.org/wiki/Top_post
+  D: Dove posso trovare informazioni riguardo alle "risposte in cima"?
+  R: Perché incasina il normale ordine con cui si legge un testo.
+  D: Perché è così terribile rispondere in cima?
+  R: Risposte in cima.
+  Q: Qual è la cosa più fastidiosa nei messaggi di posta elettronica?
+
+Allo stesso modo, per favore eliminate tutte le citazioni non necessarie per la
+vostra risposta. Questo permette di trovare più facilmente le risposte, e
+permette di risparmiare tempo e spazio. Per maggiori dettagli:
+http://daringfireball.net/2007/07/on_top ::
+
+  R: No.
+  D: Dovrei includere un blocco di citazione dopo la mia risposta?
+
 .. _it_resend_reminders:
 
 Non scoraggiatevi - o impazientitevi
index 8d856ebe873c65162c213eba423dcd054c52366f..872876c6789649f47bff78f5cfa481cf387bc34c 100644 (file)
@@ -110,7 +110,7 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを
 新しいドキュメントファイルも追加することを勧めます。
 カーネルの変更が、カーネルがユーザ空間に公開しているインターフェイスの
 変更を引き起こす場合、その変更を説明するマニュアルページのパッチや情報
-をマニュアルページのメンテナ mtk.manpages@gmail.com に送り、CC を
+をマニュアルページのメンテナ alx@kernel.org に送り、CC を
 linux-api@vger.kernel.org に送ることを勧めます。
 
 以下はカーネルソースツリーに含まれている読んでおくべきファイルの一覧で
index c543b495c042377b9347817c0eb41d041ed890c8..274ef4ad96b972a24dea7e3f6660f626632522eb 100644 (file)
@@ -7,7 +7,7 @@ Traducción al español
 
        \kerneldocCJKoff
 
-:maintainer: Carlos Bilbao <carlos.bilbao@amd.com>
+:maintainer: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_disclaimer:
 
index 27097a808c8840e6f89b4032927f702081ac296e..153e571307750486732652758e5f4183dd57d50f 100644 (file)
@@ -1,6 +1,6 @@
 NOTE:
 This is a version of Documentation/memory-barriers.txt translated into
-Spanish by Carlos Bilbao <carlos.bilbao@amd.com>. If you find any
+Spanish by Carlos Bilbao <carlos.bilbao.osdev@gmail.com>. If you find any
 difference between this document and the original file or a problem with
 the translation, please contact the maintainer of this file. Please also
 note that the purpose of this file is to be easier to read for non English
@@ -18,7 +18,7 @@ Documento original: David Howells <dhowells@redhat.com>
     Will Deacon <will.deacon@arm.com>
     Peter Zijlstra <peterz@infradead.org>
 
-Traducido por: Carlos Bilbao <carlos.bilbao@amd.com>
+Traducido por: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 Nota: Si tiene alguna duda sobre la exactitud del contenido de esta
 traducción, la única referencia válida es la documentación oficial en
 inglés.
diff --git a/Documentation/translations/sp_SP/process/1.Intro.rst b/Documentation/translations/sp_SP/process/1.Intro.rst
new file mode 100644 (file)
index 0000000..9b92b6c
--- /dev/null
@@ -0,0 +1,302 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/1.Intro.rst
+:Translator: Avadhut Naik <avadhut.naik@amd.com>
+
+.. _sp_development_process_intro:
+
+Introducción
+============
+
+Resumen ejecutivo
+-----------------
+
+El resto de esta sección cubre el alcance del proceso de desarrollo del
+kernel y los tipos de frustraciones que los desarrolladores y sus
+empleadores pueden encontrar allí. Hay muchas razones por las que el
+código del kernel debe fusionarse con el kernel oficial (“mainline”),
+incluyendo la disponibilidad automática para los usuarios, el apoyo de la
+comunidad en muchas formas, y la capacidad de influir en la dirección del
+desarrollo del kernel. El código contribuido al kernel de Linux debe
+estar disponible bajo una licencia compatible con GPL.
+
+:ref:`sp_development_process` introduce el proceso de desarrollo, el ciclo
+de lanzamiento del kernel y la mecánica de la "ventana de combinación"
+(merge window). Se cubren las distintas fases en el desarrollo del parche,
+la revisión y, el ciclo de fusión. Hay algunas discusiones sobre
+herramientas y listas de correo. Se anima a los desarrolladores que deseen
+comenzar con el desarrollo del kernel a encontrar y corregir errores como
+ejercicio inicial.
+
+:ref:`sp_development_early_stage` cubre la planificación de proyectos en
+etapas tempranas, con énfasis en involucrar a la comunidad de desarrollo
+lo antes posible.
+
+:ref:`sp_development_coding` trata sobre el proceso de codificación. Se
+discuten varios escollos encontrados por otros desarrolladores. Se cubren
+algunos requisitos para los parches, y hay una introducción a algunas de
+las herramientas que pueden ayudar a garantizar que los parches del kernel
+sean correctos.
+
+:ref:`sp_development_posting` trata sobre el proceso de enviar parches para
+su revisión. Para ser tomados en serio por la comunidad de desarrollo,
+los parches deben estar correctamente formateados y descritos, y deben
+enviarse al lugar correcto. Seguir los consejos de esta sección debería
+ayudar a garantizar la mejor recepción posible para su trabajo.
+
+:ref:`sp_development_followthrough` cubre lo que sucede después de publicar
+parches; el trabajo está lejos de terminar en ese momento. Trabajar con
+revisores es una parte crucial del proceso de desarrollo; esta sección
+ofrece varios consejos sobre cómo evitar problemas en esta importante
+etapa. Se advierte a los desarrolladores que no asuman que el trabajo está
+terminado cuando un parche se fusiona en mainline.
+
+:ref:`sp_development_advancedtopics` introduce un par de temas “avanzados”:
+la administración de parches con git y la revisión de parches publicados
+por otros.
+
+:ref:`sp_development_conclusion` concluye el documento con punteros a las
+fuentes para obtener más información sobre el desarrollo del kernel.
+
+De qué trata este documento
+---------------------------
+
+El kernel de Linux, con más de 8 millones de líneas de código y más de
+1000 colaboradores en cada versión, en uno de los proyectos de software
+libre más grandes y activos que existen. Desde sus humildes comienzos en
+1991, este kernel ha evolucionado hasta convertirse en el mejor componente
+del sistema operativo que se ejecuta en reproductores de música digital
+de bolsillo, PC de escritorio, las supercomputadoras más grandes que
+existen y todo tipo de sistemas intermedios. Es una solución robusta,
+eficiente, y escalable para casi cualquier situación.
+
+Con el crecimiento de Linux, ha llegado un aumento en el número de
+desarrolladores (y empresas) que desean participar en su desarrollo. Los
+vendedores de hardware quieren asegurarse de que Linux sea compatible con
+sus productos, lo que hace que esos productos sean atractivos para los
+usuarios de Linux. Los vendedores de sistemas embebidos, que utilizan
+Linux como componente de un producto integrado, quieren que Linux sea lo
+más capaz y adecuado posible para tarea en cuestión. Los distribuidores
+y otros vendedores de software que basan sus productos en Linux tienen un
+claro interés en las capacidades, el rendimiento, y la fiabilidad del
+kernel de Linux. Y los usuarios finales, también, a menudo desearán
+cambiar Linux para que se adapte mejor a sus necesidades.
+
+Una de las características más convincentes de Linux es que es accesible
+a estos desarrolladores; cualquier persona con las habilidades necesarias
+puede mejorar Linux e influir en la dirección de su desarrollo. Los
+productos propietarios no pueden ofrecer este tipo de apertura, que es una
+característica del proceso de software libre. Pero, en todo caso, el
+kernel es aún más libre que la mayoría de los otros proyectos de software
+libre. Un ciclo típico de desarrollo de kernel de tres meses puede
+involucrar a más de 1000 desarrolladores que trabajan para más de 100
+empresas diferentes (o sin pertenecer a ninguna empresa).
+
+Trabajar con la comunidad de desarrollo del kernel no es especialmente
+difícil. Pero, a pesar de eso, muchos colaboradores potenciales han
+experimentado dificultades al tratar de hacer el trabajo del kernel. La
+comunidad del kernel ha desarrollado sus propias formas distintivas de
+operar, lo que le permite funcionar de manera fluida (y producir un
+producto de alta calidad) en un entorno donde miles de líneas de código
+se cambian todos los días. Por lo tanto, no es sorprendente que el
+proceso de desarrollo del kernel de Linux difiera mucho de los métodos de
+desarrollo propietarios.
+
+El proceso de desarrollo del kernel puede parecer extraño e intimidante
+para los nuevos desarrolladores, pero hay buenas razones y una sólida
+experiencia detrás de él. Un desarrollador que no entienda las formas de
+la comunidad del kernel (o, peor aún, que intente burlarse o eludirlas)
+tendrá una experiencia frustrante por delante. La comunidad de
+desarrollo, si bien es servicial para aquellos que están tratando de
+aprender, tiene poco tiempo para aquellos que no escuchan o que no se
+preocupan por el proceso de desarrollo.
+
+Se espera que quienes lean este documento puedan evitar esa experiencia
+frustrante. Hay mucho material aquí, pero el esfuerzo que implica leerlo
+será recompensado en poco tiempo. La comunidad de desarrollo siempre
+necesita desarrolladores que ayudan a mejorar el kernel; el siguiente
+texto debería ayudarle – o a quienes trabajan para usted, a unirse a
+nuestra comunidad.
+
+Créditos
+--------
+
+Este documento fue escrito por Jonathan Corbet, corbet@lwn.net. Ha sido
+mejorado por los comentarios de Johannes Berg, James Berry, Alex Chiang,
+Roland Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur
+Marsh, Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata y
+Jochen Voß.
+Este trabajo fue respaldado por la Fundación Linux; gracias especialmente
+a Amanda McPherson, quien reconoció el valor de este esfuerzo e hizo que
+todo sucediera.
+
+Importancia de integrar el código en el mainline
+------------------------------------------------
+
+Algunas empresas y desarrolladores ocasionalmente se preguntan por qué
+deberían molestarse en aprender cómo trabajar con la comunidad del
+kernel y obtener su código en el kernel mainline (el “mainline” es el
+kernel mantenido por Linus Torvalds y utilizado como base por los
+distribuidores de Linux. A corto plazo, contribuir con código puede
+parecer un gasto evitable; parece más fácil mantener el código separado
+y dar soporte a los usuarios directamente. La verdad del asunto es que
+mantener el código separado (“fuera del árbol”) es pan para hoy y hambre
+para mañana.
+
+Para ilustrar los costos del código fuera-del-árbol, aquí hay algunos
+aspectos relevantes del proceso de desarrollo del kernel. La mayoría de
+estos se discutirán con mayor detalle más adelante en este documento.
+Considerar:
+
+- El código que se ha fusionado con el kernel mainline está disponible
+  para todos los usuarios de Linux. Estará presente automáticamente en
+  todas las distribuciones que lo habiliten. No hay necesidad de discos
+  de controladores, descargas, o las molestias de admitir múltiples
+  versiones de múltiples distribuciones; todo simplemente funciona, para
+  el desarrollador y para el usuario. La incorporación al mainline
+  resuelve un gran número de problemas de distribución y soporte.
+
+- Mientras los desarrolladores del kernel se esfuerzan por mantener una
+  interfaz estable para el espacio de usuario, la API interna de kernel
+  está en constante cambio. La falta de una interfaz interna estable es
+  una decisión deliberada de diseño; permite realizar mejoras
+  fundamentales en cualquier momento y da como resultado un código de
+  mayor calidad. Pero uno resultado de esa política es que cualquier
+  código fuera-del-árbol requiere un mantenimiento constante si va a
+  funcionar con los nuevos kernels. Mantener el código fuera-del-árbol
+  requiere una cantidad significativa de trabajo sólo para que ese código
+  siga funcionando.
+
+  En su lugar, el código en el mainline no requiere este trabajo como
+  resultado de una regla simple que requiere que cualquier desarrollador
+  que realice un cambio en la API también corrija cualquier código que
+  se rompa como resultado de ese cambio. Así que, el código fusionado en
+  el mainline tiene costos de mantenimiento significativamente más bajos.
+
+- Más allá de eso, el código que está en el kernel a menudo será
+  mejorado por otros desarrolladores. Resultados sorprendentes pueden
+  provenir de capacitar a su comunidad de usuarios y clientes para mejorar
+  su producto.
+
+- El código del kernel se somete a revisión, tanto antes como después
+  de fusionarse con el mainline. No importa cuán fuertes sean las
+  habilidades del desarrollador original, este proceso de revisión
+  invariablemente encuentra formas en las que se puede mejorar el código.
+  A menudo la revisión encuentra errores graves y problemas de seguridad.
+  Esto es especialmente cierto para el código que se ha desarrollado en
+  un entorno cerrado; dicho código se beneficia fuertemente de la
+  revisión por desarrolladores externos. El código fuera-del-árbol es
+  de menor calidad.
+
+- La participación en el proceso de desarrollo es su manera de influir en
+  la dirección del desarrollo del kernel. Los usuarios que se quejan
+  desde el sofa son escuchados, pero los desarrolladores activos tienen
+  una voz más fuerte – y la capacidad de implementar cambios que hacen
+  que el kernel funcione mejor para sus necesidades.
+
+- Cuando el código se mantiene por separado, siempre existe la posibilidad
+  de que un tercero contribuya a una implementación diferente de una
+  característica similar. Si eso sucede, conseguir que su código
+  fusionado será mucho más difícil – hasta el punto de la imposibilidad.
+  Entonces se enfrentará a las desagradables alternativas de (1) mantener
+  una característica no estándar fuera del árbol indefinidamente, o
+  (2) abandonar su código y migrar sus usuarios a la versión en el árbol.
+
+- La contribución del código es la acción fundamental que hace que todo
+  el proceso funcione. Al contribuir con su código, puede agregar nuevas
+  funcionalidades al kernel y proporcionar capacidades y ejemplos que son
+  útiles para otros desarrolladores del kernel. Si ha desarrollado código
+  para Linux (o está pensando en hacerlo), claramente tiene un interés
+  en el éxito continuo de esta plataforma; contribuir con código es una
+  de las mejores maneras de ayudar a garantizar ese éxito.
+
+Todo el razonamiento anterior se aplica a cualquier código de kernel
+fuera-del-árbol, incluido el código que se distribuye en forma propietaria
+y únicamente en binario. Sin embargo, hay factores adicionales que deben
+tenerse en cuenta antes de considerar cualquier tipo de distribución de
+código de kernel únicamente en binario. Estos incluyen:
+
+- Las cuestiones legales en torno a la distribución de módulos
+  propietarios del kernel son, en el mejor de los casos, confusas;
+  bastantes titulares de derechos de autor del kernel creen que la
+  mayoría de los módulos binarios son productos derivados del kernel y
+  que, como resultado, su distribución es una violación de la licencia
+  Pública General de GNU (sobre la que se dirá más adelante). El autor
+  de este texto no es abogado, y nada en este documento puede considerarse
+  asesoramiento legal. Solo los tribunales pueden determinar el verdadero
+  estatus legal de los módulos de código cerrado. Pero la incertidumbre
+  que acecha a esos módulos está ahí a pesar de todo.
+
+- Los módulos binarios aumentan enormemente la dificultad de depurar
+  problemas del kernel, hasta el punto de que la mayoría de los
+  desarrolladores del kernel ni siquiera lo intentarán. Por lo tanto,
+  la distribución de módulos únicamente en binario hará que sea más
+  difícil para sus usuarios obtener soporte de la comunidad.
+
+- El soporte también es más difícil para los distribuidores de módulos
+  únicamente en binario, que deben proporcionar una versión del módulo
+  para cada distribución y cada versión del kernel que deseen apoyar.
+  Podría requerir docenas de compilaciones de un solo módulo para
+  proporcionar una cobertura razonablemente completa, y sus usuarios
+  tendrán que actualizar su módulo por separado cada vez que
+  actualicen su kernel.
+
+- Todo lo que se dijo anteriormente sobre la revisión de código se aplica
+  doblemente al código cerrado. Dado que este código no está disponible
+  en absoluto, no puede haber sido revisado por la comunidad y, sin duda,
+  tendrá serios problemas.
+
+Los fabricantes de sistemas embebidos, en particular, pueden verse
+tentados a ignorar gran parte de lo que se ha dicho en esta sección
+creyendo que están enviando un producto autónomo que utiliza una
+versión de kernel congelada y no requiere más desarrollo después de su
+lanzamiento. Este argumento desaprovecha el valor de la revisión
+generalizad del código y el valor de permitir que sus usuarios agreguen
+capacidades a su producto. Pero estos productos también tienen una vida
+comercial limitada, después de la cual se debe lanzar una nueva versión.
+En ese punto, los vendedores cuyo código esté en el mainline y bien
+mantenido estarán en una posición mucho mejor para preparar el nuevo
+producto rápidamente para el mercado.
+
+Licencias
+---------
+
+El código se contribuye al kernel de Linux bajo varias licencias, pero
+todo el código debe ser compatible con la versión 2 de la Licencia
+Pública General de GNU (GPLv2), que cubre la distribución del kernel. En
+la práctica, esto significa que todas las contribuciones de código están
+cubiertas ya sea por la GPLv2 (con, opcionalmente, un lenguaje que permite
+la distribución en versiones posteriores de la GPL) o por la licencia BSD
+de tres cláusulas. Cualquier contribución que no esté cubierta por una
+licencia compatible no será aceptada en el kernel.
+
+No se requieren (ni se solicitan) cesiones de derechos de autor para el
+código aportado al kernel. Todo el código fusionado en el kernel
+mainline conserva su propiedad original; como resultado, el kernel ahora
+tiene miles de propietarios.
+
+Una implicación de esta estructura de propiedad es que cualquier intento
+de cambiar la licencia del kernel está condenado a un fracaso casi seguro.
+Hay pocos escenarios prácticos en los que se pueda obtener el acuerdo de
+todos los titulares de derechos de autor (o eliminar su código del
+kernel). Así que, en particular, no hay perspectivas de una migración a
+la versión 3 de la GPL en un futuro previsible.
+
+Es imperativo que todo el código aportado al kernel sea legítimamente
+software libre. Por esa razón, no se aceptará código de colaboradores
+anónimos (o seudónimos). Todos los colaboradores están obligados a
+“firmar” su código, indicando que el código puede ser distribuido con
+el kernel bajo la GPL. El código que no ha sido licenciado como software
+libre por su propietario, o que corre el riesgo de crear problemas
+relacionadas con los derechos de autor para el kernel (como el código que
+se deriva de esfuerzos de ingeniería inversa que carecen de las garantías
+adecuadas) no puede ser contribuido.
+
+Las preguntas sobre cuestiones relacionadas con los derechos de autor son
+comunes en las listas de correo de desarrollo de Linux. Normalmente, estas
+preguntas no recibirán escasez de respuestas, pero se debe tener en cuenta
+que las personas que responden a esas preguntas no son abogados y no
+pueden proporcionar consejo legal. Si tiene preguntas legales relacionadas
+con el código fuente de Linux, no hay sustituto para hablar con un abogado
+que entienda este campo. Confiar en las respuestas obtenidas en listas
+técnicas de correo es un asunto arriesgado.
diff --git a/Documentation/translations/sp_SP/process/2.Process.rst b/Documentation/translations/sp_SP/process/2.Process.rst
new file mode 100644 (file)
index 0000000..5993eed
--- /dev/null
@@ -0,0 +1,542 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/2.Process.rst
+:Translator: Avadhut Naik <avadhut.naik@amd.com>
+
+.. _sp_development_process:
+
+Cómo funciona el proceso de desarrollo
+======================================
+
+El desarrollo del kernel de Linux a principios de la década de 1990 fue
+un asunto relajado, con un número relativamente pequeño de usuarios y
+desarrolladores involucrados. Con una base de usuarios en los millones y
+alrededor de 2,000 desarrolladores involucrados durante un año, el kernel
+ha tenido que adaptar varios procesos para mantener el desarrollo sin
+problemas. Se requiere una comprensión solida de cómo funciona el proceso
+para ser una parte efectiva del mismo.
+
+El panorama general
+-------------------
+
+Los desarrolladores del kernel utilizan un proceso de lanzamiento basado
+en el tiempo de manera flexible, con uno nuevo lanzamiento principal del
+kernel ocurriendo cada dos o tres meses. El historial reciente de
+lanzamientos se ve así:
+
+       ======  ==================
+       5.0     Marzo 3, 2019
+       5.1     Mayo 5, 2019
+       5.2     Julio 7, 2019
+       5.3     Septiembre 15, 2019
+       5.4     Noviembre 24, 2019
+       5.5     Enero 6, 2020
+       ======  ==================
+
+Cada lanzamiento 5.x es un lanzamiento principal del kernel con nuevas
+características, cambios internos en la API y más. Un lanzamiento típico
+puede contener alrededor de 13,000 conjuntos de cambios incluyendo en
+varias centenas de miles de líneas de código. 5.x es la vanguardia del
+desarrollo del kernel de Linux; el kernel utiliza un modelo de desarrollo
+continuo que está integrando continuamente cambios importantes.
+
+Se sigue una disciplina relativamente sencilla con respecto a la fusión
+de parches para cada lanzamiento. Al comienzo de cada ciclo de desarrollo,
+se dice que la "merge window" (ventana de fusión) está abierta. En ese
+momento, el código que se considera lo suficientemente estable (y que es
+aceptado por la comunidad de desarrollo) se fusiona en el kernel mainline.
+La mayor parte de los cambios para un nuevo ciclo de desarrollo (y todos
+los cambios principales) se fusionarán durante este tiempo, a un ritmo
+cercano a los 1,000 cambios (“parches” o “conjuntos de cambios”) por
+día.
+
+(Aparte, vale la pena señalar que los cambios integrados durante la
+ventana de fusión no surgen de la nada; han sido recolectados, probados
+y montados con anticipación. Como funciona ese proceso se describirá en
+detalle más adelante).
+
+La ventana de fusión dura aproximadamente dos semanas. Al final de este
+tiempo, Linux Torvalds declarará que la ventana está cerrada y publicará
+el primero de los kernels “rc”. Para el kernel destinado a ser 5.6, por
+ejemplo, el lanzamiento al final de la ventana de fusión se llamará
+5.6-rc1. El lanzamiento -rc1 señala que el tiempo para fusionar nuevas
+características ha pasado y que el tiempo para estabilizar el siguiente
+kernel ha comenzado.
+
+Durante las próximas seis a diez semanas, solo los parches que solucionen
+problemas deben enviarse al mainline. En ocasiones, se permitirá un cambio
+más significativo, pero tales ocasiones son raras; los desarrolladores que
+intentan fusionar nuevas características fuera de la ventana de fusión
+suelen recibir una recepción poco amistosa. Como regla general, si se
+pierde la ventana de fusión de una característica determinada, lo mejor
+que puede hacer es esperar al siguiente ciclo de desarrollo. (Se hace una
+excepción ocasional para los drivers de hardware que no se admitía
+anteriormente; si no afectan a ningún código en árbol, no pueden causar
+regresiones y debería ser seguro agregarlos en cualquier momento).
+
+A medida que las correcciones se abren paso en el mainline, la tasa de
+parches se ralentizará con el tiempo. Linus lanza nuevos kernels -rc
+aproximadamente una vez a la semana; una serie normal llegará a algún
+punto entre -rc6 y -rc9 antes de que se considere que el kernel es
+suficientemente estable y realice el lanzamiento final. En ese momento,
+todo el proceso vuelve a empezar.
+
+Como ejemplo, así fue el ciclo de desarrollo de 5.4 (todas las fechas son
+de 2019):
+
+       ==============  =======================================
+       Septiembre 15   5.3 lanzamiento estable
+       Septiembre 30   5.4-rc1, la ventana de fusion se cierra
+       Octubre 6               5.4-rc2
+       Octubre 13              5.4-rc3
+       Octubre 20              5.4-rc4
+       Octubre 27              5.4-rc5
+       Noviembre 3             5.4-rc6
+       Noviembre 10    5.4-rc7
+       Noviembre 17    5.4-rc8
+       Noviembre 24    5.4 lanzamiento estable
+       ==============  =======================================
+
+¿Cómo deciden los desarrolladores cuándo cerrar el ciclo de desarrollo
+y crear el lanzamiento estable? La métrica más significativa utilizada
+es la lista de regresiones de lanzamientos anteriores. Ningunos errores
+son bienvenidos, pero aquellos que rompen sistemas que funcionaron en el
+pasado se consideran especialmente graves. Por esta razón, los parches
+que causan regresiones se ven con malos ojos y es bastante probable que
+se reviertan durante el periodo de estabilización.
+
+El objetivo de los desarrolladores es corregir todas las regresiones
+conocidas antes de que se realice el lanzamiento estable. En el mundo
+real, este tipo de perfección es difícil de lograr; hay demasiados
+variables en un proyecto de este tamaño. Llega un punto en el que
+retrasar el lanzamiento final solo empeora el problema; la pila de cambios
+que esperan la siguiente ventana de fusión crecerá, creando aún más
+regresiones la próxima vez. Por lo tanto, la mayoría de los kernels 5.x
+se lanzan con un punado de regresiones conocidas, aunque, con suerte,
+ninguna de ellas es seria.
+
+Una vez que se realiza un lanzamiento estable, su mantenimiento continuo
+se transfiere al “equipo estable”, actualmente encabezado por Greg
+Kroah-Hartman. El equipo estable lanzará actualizaciones ocasionales al
+lanzamiento estable utilizando el esquema de numeración 5.x.y. Para ser
+considerado para un lanzamiento de actualización, un parche debe
+(1) corregir un error significativo y (2) ya estar fusionado en el
+mainline para el siguiente kernel de desarrollo. Por lo general, los
+kernels recibirán actualizaciones estables durante un poco más de un
+ciclo de desarrollo después de su lanzamiento inicial. Así, por ejemplo,
+la historia del kernel 5.2 se veía así (todas las fechas en 2019):
+
+       ==============  ===============================
+       Julio 7                 5.2 lanzamiento estable
+       Julio 14                5.2.1
+       Julio 21                5.2.2
+       Julio 26                5.2.3
+       Julio 28                5.2.4
+       Julio 31                5.2.5
+       ...                             ...
+       Octubre 11              5.2.21
+       ==============  ===============================
+
+5.2.21 fue la última actualización estable del lanzamiento 5.2.
+
+Algunos kernels se designan como kernels “a largo plazo”; recibirán
+soporte durante un periodo más largo. Consulte el siguiente enlace para
+obtener la lista de versiones activas del kernel a largo plazos y sus
+maintainers:
+
+       https://www.kernel.org/category/releases.html
+
+La selección de un kernel para soporte a largo plazo es puramente una
+cuestión de que un maintainer tenga la necesidad y el tiempo para
+mantener ese lanzamiento. No hay planes conocidos para ofrecer soporte a
+largo plazo para ningún lanzamiento especifico próximo.
+
+Ciclo de vida de un parche
+--------------------------
+
+Los parches no van directamente desde el teclado del desarrollador al
+kernel mainline. Hay, en cambio, un proceso algo complicado (aunque algo
+informal) diseñado para garantizar que cada parche sea revisado en cuanto
+a calidad y que cada parche implemente un cambio que es deseable tener en
+el mainline. Este proceso puede ocurrir rápidamente para correcciones
+menores, o, en el caso de cambios grandes y controvertidos, continuar
+durante años. Gran parte de la frustración de los desarrolladores proviene
+de la falta de compresión de este proceso o de sus intentos de eludirlo.
+
+Con la esperanza de reducir esa frustración, este documento describirá
+cómo un parche entra en el kernel. Lo que sigue a continuación es una
+introducción que describe el proceso de una manera tanto idealizada. Un
+tratamiento mucho más detallado vendrá en secciones posteriores.
+
+Las etapas por las que pasa un parche son, generalmente:
+
+ - Diseño. Aquí es donde se establecen los requisitos reales para el
+   parche – y la forma en que se cumplirán esos requisitos. El trabajo
+   de diseño a menudo se realiza sin involucrar a la comunidad, pero es
+   mejor hacer este trabajo de manera abierta si es posible; puede ahorrar
+   mucho tiempo rediseñando las cosas más tarde.
+
+ - Revisión inicial. Los parches se publican en la lista de correo
+   relevante y los desarrolladores en esa lista responden con cualquier
+   comentario que puedan tener. Este proceso debería revelar cualquier
+   problema importante con un parche si todo va bien.
+
+ - Revisión más amplia. Cuando el parche se acerca a estar listo para su
+   inclusión en el mainline, debe ser aceptado por un maintainer del
+   subsistema relevante – aunque esta aceptación no es una garantía de
+   que el parche llegara hasta el mainline. El parche aparecerá en el
+   árbol de subsistemas del maintainer y en los árboles -next (descritos
+   a continuación). Cuando el proceso funciona, este paso conduce a una
+   revisión exhaustiva del parche y al descubrimiento de cualquier
+   problema resultante de la integración de este parche con el trabajo
+   realizado por otros.
+
+ - Tenga en cuenta que la mayoría de los maintainers también tienen
+   trabajos diurnos, por lo que fusionar su parche no puede ser su máxima
+   prioridad. Si su parche está recibiendo comentarios sobre los cambios
+   que se necesitan, debería realizar esos cambios o justificar por qué
+   no deberían realizarse. Si su parche no tiene quejas de revisión, pero
+   no está siendo fusionado por el maintainer apropiado del subsistema o
+   del driver, debe ser persistente en la actualización del parche
+   al kernel actual para que se aplique limpiamente y seguir enviándolo
+   para su revisión y fusión.
+
+ - Fusión en el mainline. Eventualmente, un parche exitoso se fusionará
+   en el repositorio mainline administrado por Linux Torvalds. Mas
+   comentarios y/o problemas pueden surgir en este momento; es importante
+   que el desarrollador responda a estos y solucione cualquier problema
+   que surja.
+
+ - Lanzamiento estable. El número de usuarios potencialmente afectados por
+   el parche es ahora grande, por lo que, una vez más, pueden surgir
+   nuevos problemas.
+
+ - Mantenimiento a largo plazo. Si bien un desarrollador puede olvidarse
+   del código después de fusionarlo, ese comportamiento tiende a dejar
+   una impresión negativa en la comunidad de desarrollo. Fusionar el
+   código elimina parte de la carga de mantenimiento; otros solucionarán
+   los problemas causados por los cambios en la API. Sin embargo, el
+   desarrollador original debe seguir asumiendo la responsabilidad del
+   código si quiere seguir siendo útil a largo plazo.
+
+Uno de los peores errores cometidos por los desarrolladores del kernel
+(o sus empleadores) es tratar de reducir el proceso a un solo paso de
+“fusión en el mainline”. Este enfoque conduce invariablemente a la
+frustración de todos los involucrados.
+
+Cómo se integran los parches en el kernel
+-----------------------------------------
+
+Hay exactamente una persona que puede fusionar parches en el repositorio
+mainline del kernel: Linus Torvalds. Pero, por ejemplo, de los más de
+9,500 parches que se incluyeron en el kernel 2.6.38, solo 112 (alrededor
+del 1.3%) fueron elegidos directamente por Linus mismo. El proyecto del
+kernel ha crecido mucho desde hace tiempo a un tamaño en el que ningún
+desarrollador individual podría inspeccionar y seleccionar todos los
+parches sin ayuda. La forma que los desarrolladores del kernel han
+abordado este crecimiento es a través del uso de un sistema jerárquico
+alrededor de una cadena de confianza.
+
+La base de código del kernel se descompone lógicamente en un conjunto de
+subsistemas: redes, soporte de arquitectura especifica, gestión de
+memoria, dispositivos de video, etc. La mayoría de los subsistemas tienen
+un maintainer designado, un desarrollador que tiene la responsabilidad
+general del código dentro de ese subsistema. Estos maintainers de
+subsistemas son los guardianes (en cierto modo) de la parte del kernel que
+gestionan; son los que (usualmente) aceptarán un parche para incluirlo en
+el kernel mainline.
+
+Cada uno de los maintainers del subsistema administra su propia versión
+del árbol de fuentes del kernel, generalmente (pero, ciertamente no
+siempre) usando la herramienta de administración de código fuente de git.
+Herramientas como git (y herramientas relacionadas como quilt o mercurial)
+permiten a los maintainers realizar un seguimiento de una lista de
+parches, incluida la información de autoría y otros metadatos. En
+cualquier momento, el maintainer puede identificar qué parches de su
+repositorio no se encuentran en el mainline.
+
+Cuando se abre la ventana de fusión, los maintainers de nivel superior
+le pedirán a Linus que “extraiga” los parches que han seleccionado para
+fusionar de sus repositorios. Si Linus está de acuerdo, el flujo de
+parches fluirá hacia su repositorio, convirtiéndose en parte del kernel
+mainline. La cantidad de atención que Linus presta a los parches
+específicos recibidos en una operación de extracción varia. Está claro
+que, a veces, examina bastante de cerca. Pero, como regla general, Linus
+confía en que los maintainers del subsistema no envíen parches
+defectuosos al upstream.
+
+Los maintainers de subsistemas, a su vez, pueden extraer parches de otros
+maintainers. Por ejemplo, el árbol de red se construye a partir de
+parches que se acumulan primero en arboles dedicados a drivers de
+dispositivos de red, redes inalámbricas, etc. Esta cadena de repositorios
+puede ser arbitrariamente larga, aunque rara vez supera los dos o tres
+enlaces. Dado que cada maintainer de la cadena confía en los que
+administran árboles de nivel inferior, este proceso se conoce como la
+“cadena de confianza”.
+
+Claramente, en un sistema como este, lograr que los parches se integren
+en el kernel depende de encontrar el maintainer adecuado. Enviar parches
+directamente a Linus no es normalmente la forma correcta de hacerlo.
+
+Árboles siguientes (next)
+-------------------------
+
+La cadena de árboles de subsistemas guía el flujo de parches en el
+kernel, pero también plantea una pregunta interesante: ¿Qué pasa si
+alguien quiere ver todos los parches que se están preparando para la
+próxima ventana de fusión? Los desarrolladores estarán interesados en
+saber que otros cambios están pendientes para ver si hay algún conflicto
+del que preocuparse; un parche que cambia un prototipo de función del
+núcleo del kernel, por ejemplo, entrará en conflicto con cualquier otro
+parche que utilice la forma anterior de esa función. Los revisores y
+probadores quieren tener acceso a los cambios en su forma integrada antes
+de que todos esos cambios se integren en el kernel mainline. Uno podría
+extraer cambios de todos los árboles de subsistemas interesantes, pero
+eso sería un trabajo tedioso y propenso a errores.
+
+La respuesta viene en forma de árboles -next, donde los árboles de
+subsistemas se recopilan para pruebas y revisiones. El más antiguo de
+estos árboles, mantenido por Andrew Morton, se llama “-mm” (por gestión
+de la memoria, que es como comenzó). El árbol “-mm” integra parches
+de una larga lista de árboles de subsistemas; también tiene algunos
+parches destinados a ayudar con la depuración.
+
+Más allá de eso, -mm contiene una colección significativa de parches
+que han sido seleccionados directamente por Andrew. Estos parches pueden
+haber sido publicados en una lista de correo o aplicarse a una parte del
+kernel para la que no hay un árbol de subsistemas designado. Como
+resultado, -mm funciona como una especie de árbol de subsistemas de
+último recurso; si no hay otro camino obvio para un parche en el mainline,
+es probable que termine en -mm. Los parches misceláneos que se acumulan
+en -mm eventualmente se enviarán a un árbol de subsistema apropiado o se
+enviarán directamente a Linus. En un ciclo de desarrollo típico,
+aproximadamente el 5-10% de los parches que van al mainline llegan allí
+a través de -mm.
+
+El parche -mm actual está disponible en el directorio “mmotm” (-mm
+del momento) en:
+
+       https://www.ozlabs.org/~akpm/mmotm/
+
+Sin embargo, es probable que el uso del árbol MMOTM sea una experiencia
+frustrante; existe una posibilidad definitiva de que ni siquiera se
+compile.
+
+El árbol principal para la fusión de parches del siguiente ciclo es
+linux-next, mantenido por Stephen Rothwell. El árbol linux-next es, por
+diseño, una instantánea de cómo se espera que se vea el mainline después
+de que se cierre la siguiente ventana de fusión. Los árboles linux-next
+se anuncian en las listas de correo linux-kernel y linux-next cuando se
+ensamblan; Se pueden descargar desde:
+
+       https://www.kernel.org/pub/linux/kernel/next/
+
+Linux-next se ha convertido en una parte integral del proceso de
+desarrollo del kernel; todos los parches fusionados durante una ventana
+de fusión determinada deberían haber encontrado su camino en linux-next
+en algún momento antes de que se abra la ventana de fusión.
+
+Árboles de staging
+------------------
+
+El árbol de fuentes del kernel contiene el directorio drivers/staging/,
+donde residen muchos subdirectorios para drivers o sistemas de archivos
+que están en proceso de ser agregados al árbol del kernel. Permanecen
+en drivers/staging mientras aún necesitan más trabajo; una vez
+completados, se pueden mover al kernel propiamente dicho. Esta es una
+forma de realizar un seguimiento de los drivers drivers que no están a la
+altura de la codificación o los estándares de calidad del kernel de
+Linux, pero que las personas pueden querer usarlos y realizar un
+seguimiento del desarrollo.
+
+Greg Kroah-Hartman mantiene actualmente el árbol de staging. Los drivers
+que aun necesitan trabajo se le envían, y cada driver tiene su propio
+subdirectorio en drivers/staging/. Junto con los archivos de origen del
+driver, también debe haber un archivo TODO en el directorio. El archivo
+TODO enumera el trabajo pendiente que el driver necesita para ser aceptado
+en el kernel propiamente dicho, así como una lista de personas a las que
+Cc’d para cualquier parche para el driver. Las reglas actuales exigen
+que los drivers que contribuyen a staging deben, como mínimo, compilarse
+correctamente.
+
+El staging puede ser una forma relativamente fácil de conseguir nuevos
+drivers en el mainline donde, con suerte, llamarán la atención de otros
+desarrolladores y mejorarán rápidamente. Sin embargo, la entrada en el
+staging no es el final de la historia; el código que no está viendo
+progreso regular eventualmente será eliminado. Los distribuidores también
+tienden a ser relativamente reacios a habilitar los drivers de staging.
+Por lo tanto, el staging es, en el mejor de los casos, una parada en el
+camino para hacia convertirse en un apropiado driver del mainline.
+
+Herramientas
+------------
+
+Como se puede ver en el texto anterior, el proceso de desarrollo del
+kernel depende en gran medida de la capacidad de dirigir colecciones de
+parches en varias direcciones. Todo ello no funcionaría tan bien como lo
+hace sin herramientas apropiadamente potentes. Los tutoriales sobre cómo
+usar estas herramientas están mucho más allá del alcance de este
+documento, pero hay espacio para algunos consejos.
+
+Con mucho, el sistema de gestión de código fuente dominante utilizado
+por la comunidad del kernel es git. Git es uno de los varios sistemas de
+control de versiones distribuidos que se están desarrollando en la
+comunidad de software libre. Está bien ajustado para el desarrollo de
+kernel, ya que funciona bastante bien cuando se trata de grandes
+repositorios y grandes cantidades de parches. También tiene la reputación
+de ser difícil de aprender y usar, aunque ha mejorado con el tiempo.
+Algún tipo de familiaridad con git es casi un requisito para los
+desarrolladores del kernel; incluso si no lo usan para su propio
+trabajo, necesitarán git para mantenerse al día con lo que otros
+desarrolladores (y el mainline) están haciendo.
+
+Git ahora está empaquetado por casi todas las distribuciones de Linux.
+Hay una página de inicio en:
+
+       https://git-scm.com/
+
+Esa página tiene punteros a documentación y tutoriales.
+
+Entre los desarrolladores de kernel que no usan git, la opción más
+popular es casi con certeza Mercurial:
+
+       https://www.selenic.com/mercurial/
+
+Mercurial comparte muchas características con git, pero proporciona una
+interfaz que muchos encuentran más fácil de usar.
+
+Otra herramienta que vale la pena conocer es Quilt:
+
+       https://savannah.nongnu.org/projects/quilt/
+
+Quilt es un sistema de gestión de parches, en lugar de un sistema de
+gestión de código fuente. No rastrea el historial a lo largo del tiempo;
+en cambio, está orientado al seguimiento de un conjunto especifico de
+cambios en relación con una base de código en evolución. Algunos de los
+principales maintainers de subsistemas utilizan Quilt para gestionar los
+parches destinados a ir upstream. Para la gestión de ciertos tipos de
+árboles (por ejemplo, -mm) Quilt es la mejor herramienta para el trabajo.
+
+Listas de correo
+----------------
+
+Una gran parte del trabajo de desarrollo del kernel de Linux se realiza a
+través de listas de correo. Es difícil ser un miembro plenamente funcional
+de la comunidad sin unirse al menos a una lista en algún parte. Pero las
+listas de correo de Linux también representan un peligro potencial para
+los desarrolladores, que corren el riesgo de quedar enterrados bajo una
+carga de correo electrónico, incumplir las convenciones utilizadas en las
+listas de Linux, o ambas cosas.
+
+La mayoría de las listas de correo del kernel se ejecutan en
+vger.kernel.org; la lista principal se puede encontrar en:
+
+       http://vger.kernel.org/vger-lists.html
+
+Sim embargo, hay listas alojadas en otros lugares; varios de ellos se
+encuentran en redhat.com/mailman/listinfo.
+
+La lista de correo principal para el desarrollo del kernel es, por
+supuesto, linux-kernel. Esta lista es un lugar intimidante; el volumen
+puede alcanzar 500 mensajes por día, la cantidad de ruido es alta, la
+conversación puede ser muy técnica y los participantes no siempre se
+preocupan por mostrar un alto grado de cortesía. Pero no hay otro lugar
+donde la comunidad de desarrollo del kernel se reúna como un todo; los
+desarrolladores que eviten esta lista se perderán información importante.
+
+Hay algunos consejos que pueden ayudar a sobrevivir en el kernel de Linux:
+
+- Haga que la lista se entregue en una carpeta separada, en lugar de su
+  buzón principal. Uno debe ser capaz de ignorar el flujo durante
+  periodos prolongados.
+
+- No trate de seguir cada conversación, nadie lo hace. Es importante
+  filtrar tanto por el tema de interés (aunque tenga en cuenta que las
+  conversaciones prolongadas pueden alejarse del asunto original sin
+  cambiar la línea de asunto del correo electrónico) por las personas
+  que participan.
+
+- No alimente a los trolls. Si alguien está tratando de provocar una
+  respuesta de enojo, ignórelos.
+
+- Al responder al correo electrónico del kernel de Linux (o al de otras
+  listas) conserve el encabezado Cc: para todos los involucrados. En
+  ausencia de una razón solida (como una solicitud explícita), nunca debe
+  eliminar destinarios. Asegúrese siempre de que la persona a la que está
+  respondiendo esté en la lista Cc:. Esta convención también hace que no
+  sea necesario solicitar explícitamente que se le copie en las respuestas
+  a sus publicaciones.
+
+- Busque en los archivos de la lista (y en la red en su conjunto) antes
+  de hacer preguntas. Algunos desarrolladores pueden impacientarse con
+  las personas que claramente no han hecho sus deberes.
+
+- Utilice respuestas intercaladas (“en línea”), lo que hace que su
+  respuesta sea más fácil de leer. (Es decir, evite top-posting – la
+  práctica de poner su respuesta encima del texto citado al que está
+  respondiendo.) Para obtener más información, consulte
+  :ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_interleaved_replies>`.
+
+- Pregunte en la lista de correo correcta. linux-kernel puede ser el
+  punto de encuentro general, pero no es el mejor lugar para encontrar
+  desarrolladores de todos los subsistemas.
+
+El último punto, encontrar la lista de correo correcta, es una fuente
+común de errores para desarrolladores principiantes. Alguien que haga
+una pregunta relacionada con las redes en linux-kernel seguramente
+recibirá una surgencia educada para preguntar en la lista de netdev en su
+lugar, ya que esa es la lista frecuentada por la mayoría de los
+desarrolladores de redes. Existen otras listas para los subsistemas SCSI,
+video4linux, IDE, sistema de archivos, etc. El mejor lugar para buscar
+listas de correo es en el archivo MAINTAINERS incluido con el código
+fuente del kernel.
+
+Comenzar con el desarrollo del kernel
+-------------------------------------
+
+Las preguntas sobre como comenzar con el proceso de desarrollo del kernel
+son comunes, tanto de individuos como de empresas. Igualmente comunes son
+los pasos en falso que hacen que el comienzo de la relación sea más
+difícil de lo que tiene que ser.
+
+Las empresas a menudo buscan contratar desarrolladores conocidos para
+iniciar un grupo de desarrollo. De hecho, esta puede ser una técnica
+efectiva. Pero también tiende a ser caro y no hace mucho para crecer el
+grupo de desarrolladores de kernel experimentados. Es posible poner al
+día a los desarrolladores internos en el desarrollo de kernel de Linux,
+dada la inversión de algún tiempo. Tomarse este tiempo puede dotar a un
+empleador de un grupo de desarrolladores que comprendan tanto el kernel
+como la empresa, y que también puedan ayudar a educar a otros. A medio
+plazo, este es a menudo el enfoque más rentable.
+
+Los desarrolladores individuales, a menudo, comprensiblemente, no tienen
+un lugar para empezar. Comenzar con un proyecto grande puede ser
+intimidante; a menudo uno quiere probar las aguas con algo más pequeño
+primero. Este es el punto en el que algunos desarrolladores se lanzan a
+la creación de parches para corregir errores ortográficos o problemas
+menores de estilo de codificación. Desafortunadamente, dicho parches
+crean un nivel de ruido que distrae a la comunidad de desarrollo en su
+conjunto, por lo que, cada vez más, se los mira con desprecio. Los nuevos
+desarrolladores que deseen presentarse a la comunidad no recibirán la
+recepción que desean por estos medios.
+
+Andrew Morton da este consejo (traducido) para los aspirantes a
+desarrolladores de kernel.
+
+::
+
+       El proyecto #1 para los principiantes en el kernel seguramente debería
+       ser “asegúrese de que el kernel funcione perfectamente en todo momento
+       en todas las máquinas que pueda conseguir”. Por lo general, la forma
+       de hacer esto es trabajar con otros para arreglar las cosas (¡esto
+       puede requerir persistencia!), pero eso está bien, es parte del
+       desarrollo del kernel.
+
+(https://lwn.net/Articles/283982/)
+
+En ausencia de problemas obvios que solucionar, se aconseja a los
+desarrolladores que consulten las listas actuales de regresiones y errores
+abiertos en general. Nunca faltan problemas que necesitan solución; al
+abordar estos problemas, los desarrolladores ganarán experiencia con el
+proceso mientras, al mismo tiempo, se ganarán el respeto del resto de la
+comunidad de desarrollo.
diff --git a/Documentation/translations/sp_SP/process/3.Early-stage.rst b/Documentation/translations/sp_SP/process/3.Early-stage.rst
new file mode 100644 (file)
index 0000000..71cfb3f
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/3.Early-stage.rst
+
+.. _sp_development_early_stage:
+
+Planificación en etapa inicial
+==============================
+
+.. warning::
+       TODO aún no traducido
diff --git a/Documentation/translations/sp_SP/process/4.Coding.rst b/Documentation/translations/sp_SP/process/4.Coding.rst
new file mode 100644 (file)
index 0000000..d9436e0
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/4.Coding.rst
+
+.. _sp_development_coding:
+
+Conseguir el código correcto
+============================
+
+.. warning::
+       TODO aún no traducido
diff --git a/Documentation/translations/sp_SP/process/5.Posting.rst b/Documentation/translations/sp_SP/process/5.Posting.rst
new file mode 100644 (file)
index 0000000..50a3bc5
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/5.Posting.rst
+
+.. _sp_development_posting:
+
+Publicar parches
+================
+
+.. warning::
+       TODO aún no traducido
diff --git a/Documentation/translations/sp_SP/process/6.Followthrough.rst b/Documentation/translations/sp_SP/process/6.Followthrough.rst
new file mode 100644 (file)
index 0000000..f0acf90
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/6.Followthrough.rst
+
+.. _sp_development_followthrough:
+
+Seguimiento
+===========
+
+.. warning::
+       TODO aún no traducido
diff --git a/Documentation/translations/sp_SP/process/7.AdvancedTopics.rst b/Documentation/translations/sp_SP/process/7.AdvancedTopics.rst
new file mode 100644 (file)
index 0000000..5537598
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/7.AdvancedTopics.rst
+
+.. _sp_development_advancedtopics:
+
+Temas avanzados
+===============
+
+.. warning::
+       TODO aún no traducido
diff --git a/Documentation/translations/sp_SP/process/8.Conclusion.rst b/Documentation/translations/sp_SP/process/8.Conclusion.rst
new file mode 100644 (file)
index 0000000..dd181cb
--- /dev/null
@@ -0,0 +1,11 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/8.Conclusion.rst
+
+.. _sp_development_conclusion:
+
+Para más información
+====================
+
+.. warning::
+       TODO aún no traducido
index adc6c770cc37799ad25b8057e22cebfb87df031d..a6c08613aefccc6a2ced305e3f418b97bb808ce0 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/code-of-conduct.rst <code_of_conduct>`
-:Translator: Contributor Covenant and Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Contributor Covenant and Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_code_of_conduct:
 
index a37274764371199862d36f41915161c428899b23..b5a84df44cea04c9f0c4eb7249e132ec08c26b2c 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/coding-style.rst <submittingpatches>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_codingstyle:
 
diff --git a/Documentation/translations/sp_SP/process/development-process.rst b/Documentation/translations/sp_SP/process/development-process.rst
new file mode 100644 (file)
index 0000000..40d7408
--- /dev/null
@@ -0,0 +1,27 @@
+.. include:: ../disclaimer-sp.rst
+
+:Original: Documentation/process/development-process.rst
+:Translator: Avadhut Naik <avadhut.naik@amd.com>
+
+.. _sp_development_process_main:
+
+Guía del proceso de desarrollo del kernel
+=========================================
+
+El propósito de este documento es ayudar a los desarrolladores (y sus
+gerentes) a trabajar con la comunidad de desarrollo con un mínimo de
+frustración. Es un intento de documentar cómo funciona esta comunidad
+de una manera accesible para aquellos que no están familiarizados
+íntimamente con el desarrollo del kernel de Linux (o, de hecho, el
+desarrollo de software libre en general). Si bien hay algo de material
+técnico aquí, este es en gran medida una discusión orientada al proceso
+que no requiere un conocimiento profundo de la programación del kernel
+para entenderla.
+
+.. toctree::
+   :caption: Contenido
+   :numbered:
+   :maxdepth: 2
+
+   1.Intro
+   2.Process
index fdf1e51b84e4db893a1a66df2377c570f99fc9cb..55d5803daf418e8ddc390b88ceb3c9ef37eb891f 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/email-clients.rst <email_clients>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_email_clients:
 
index dd793c0f8574fe1806e5fba0c7c1adbd1acfec7a..72ea855ac9dcb4418ac18e55d61594b1aaaa4e91 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/howto.rst <process_howto>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_process_howto:
 
index 2239373b3999405bf76f9554542fb71f822c5811..4892159310fff07d43782de883a2fd0b0c7ede0f 100644 (file)
@@ -28,3 +28,4 @@
    management-style
    submit-checklist
    howto
+   development-process
index 2f9b3df8f8fab4b3a4a82280f9bebaa959df1e15..a62c6854f59b26bcfcbdcc6117c5fafc46aa3e4b 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/kernel-docs.rst <kernel_docs>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_kernel_docs:
 
index d669026940898363a5f548bbede8d6c60df2a952..d47a1c1546105aaaf945592898779af2145ccb8c 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/kernel-enforcement-statement.rst <process_statement_kernel>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_process_statement_kernel:
 
index 7c7dfb4ba80bc23c99799a70ff197084e8c2155f..32a99aac2f6cade48e871d5425c9222b3c26a809 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/magic-number.rst <magicnumbers>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_magicnumbers:
 
index 301f525372d85eed13e4eaeb8f44cf0ff4d2b3bc..ba2164057f458b8ac948834a556617b6c18087d1 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/programming-language.rst <programming_language>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_programming_language:
 
index c2757d9ab2168e3900913d970642ec8885d94c97..328ec80bd61d5e247365e825a59a3b6dcb444ca8 100644 (file)
@@ -1,7 +1,7 @@
 .. include:: ../disclaimer-sp.rst
 
 :Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
-:Translator: Carlos Bilbao <carlos.bilbao@amd.com>
+:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 
 .. _sp_submittingpatches:
 
@@ -356,6 +356,34 @@ Consulte Documentation/process/email-clients.rst para obtener
 recomendaciones sobre clientes de correo electrónico y normas de etiqueta
 en la lista de correo.
 
+.. _sp_interleaved_replies:
+
+Uso de respuestas intercaladas recortadas en las discusiones por correo electrónico
+-----------------------------------------------------------------------------------
+
+Se desaconseja encarecidamente la publicación en la parte superior de las
+discusiones sobre el desarrollo del kernel de Linux. Las respuestas
+intercaladas (o "en línea") hacen que las conversaciones sean mucho más
+fáciles de seguir. Para obtener más detalles, consulte:
+https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
+
+Como se cita frecuentemente en la lista de correo::
+
+  A: http://en.wikipedia.org/wiki/Top_post
+  Q: ¿Dónde puedo encontrar información sobre esto que se llama top-posting?
+  A: Porque desordena el orden en el que la gente normalmente lee el texto.
+  Q: ¿Por qué es tan malo el top-posting?
+  A: Top-posting.
+  Q: ¿Qué es lo más molesto del correo electrónico?
+
+Del mismo modo, por favor, recorte todas las citas innecesarias que no
+sean relevantes para su respuesta. Esto hace que las respuestas sean más
+fáciles de encontrar y ahorra tiempo y espacio. Para obtener más
+información, consulte: http://daringfireball.net/2007/07/on_top ::
+
+  A: No.
+  Q: ¿Debo incluir citas después de mi respuesta?
+
 .. _sp_resend_reminders:
 
 No se desanime o impaciente
index 7fac6f75d0782062f3f11c342068e9f13e90f2ad..fe0ff5a127f3f9255fe2606c15beb9380522cc4c 100644 (file)
@@ -7,12 +7,13 @@
 
  司延腾 Yanteng Si <siyanteng@loongson.cn>
  周彬彬 Binbin Zhou <zhoubinbin@loongson.cn>
+ 陈兴友 Xingyou Chen <rockrush@rockwork.org>
 
 .. _cn_workqueue.rst:
 
-=========================
¹¶å\8f\91管ç\90\86ç\9a\84å·¥ä½\9cé\98\9få\88\97 (cmwq)
-=========================
+========
·¥ä½\9cé\98\9få\88\97
+========
 
 :日期: September, 2010
 :作者: Tejun Heo <tj@kernel.org>
@@ -22,7 +23,7 @@
 简介
 ====
 
-在很多情况下,需要一个异步进程的执行环境,工作队列(wq)API是这种情况下
+在很多情况下,需要一个异步的程序执行环境,工作队列(wq)API是这种情况下
 最常用的机制。
 
 当需要这样一个异步执行上下文时,一个描述将要执行的函数的工作项(work,
@@ -34,8 +35,8 @@
 队列时,工作者又开始执行。
 
 
-为什么要cmwq?
-=============
+为什么要有并发管理工作队列?
+===========================
 
 在最初的wq实现中,多线程(MT)wq在每个CPU上有一个工作者线程,而单线程
 (ST)wq在全系统有一个工作者线程。一个MT wq需要保持与CPU数量相同的工
 向该函数的工作项,并在工作队列中排队等待该工作项。(就是挂到workqueue
 队列里面去)
 
-特定目的线程,称为工作线程(工作者),一个接一个地执行队列中的功能。
-如果没有工作项排队,工作者线程就会闲置。这些工作者线程被管理在所谓
-的工作者池中。
+工作项可以在线程或BH(软中断)上下文中执行。
+
+对于由线程执行的工作队列,被称为(内核)工作者([k]worker)的特殊
+线程会依次执行其中的函数。如果没有工作项排队,工作者线程就会闲置。
+这些工作者线程被管理在所谓的工作者池中。
 
 cmwq设计区分了面向用户的工作队列,子系统和驱动程序在上面排队工作,
 以及管理工作者池和处理排队工作项的后端机制。
@@ -84,6 +87,10 @@ cmwq设计区分了面向用户的工作队列,子系统和驱动程序在上
 优先级的工作项,还有一些额外的工作者池,用于服务未绑定工作队列的工
 作项目——这些后备池的数量是动态的。
 
+BH工作队列使用相同的结构。然而,由于同一时间只可能有一个执行上下文,
+不需要担心并发问题。每个CPU上的BH工作者池只包含一个用于表示BH执行
+上下文的虚拟工作者。BH工作队列可以被看作软中断的便捷接口。
+
 当他们认为合适的时候,子系统和驱动程序可以通过特殊的
 ``workqueue API`` 函数创建和排队工作项。他们可以通过在工作队列上
 设置标志来影响工作项执行方式的某些方面,他们把工作项放在那里。这些
@@ -95,9 +102,9 @@ cmwq设计区分了面向用户的工作队列,子系统和驱动程序在上
 否则一个绑定的工作队列的工作项将被排在与发起线程运行的CPU相关的普
 通或高级工作工作者池的工作项列表中。
 
-对于任何工作者池的实施,管理并发水平(有多少执行上下文处于活动状
-态)是一个重要问题。最低水平是为了节省资源,而饱和水平是指系统被
-充分使用。
+对于任何线程池的实施,管理并发水平(有多少执行上下文处于活动状
+态)是一个重要问题。cmwq试图将并发保持在一个尽可能低且充足的
+水平。最低水平是为了节省资源,而充足是为了使系统能被充分使用。
 
 每个与实际CPU绑定的worker-pool通过钩住调度器来实现并发管理。每当
 一个活动的工作者被唤醒或睡眠时,工作者池就会得到通知,并跟踪当前可
@@ -140,6 +147,17 @@ workqueue将自动创建与属性相匹配的后备工作者池。调节并发
 ``flags``
 ---------
 
+``WQ_BH``
+  BH工作队列可以被看作软中断的便捷接口。它总是每个CPU一份,
+  其中的各个工作项也会按在队列中的顺序,被所属CPU在软中断
+  上下文中执行。
+
+  BH工作队列的 ``max_active`` 值必须为0,且只能单独或和
+  ``WQ_HIGHPRI`` 标志组合使用。
+
+  BH工作项不可以睡眠。像延迟排队、冲洗、取消等所有其他特性
+  都是支持的。
+
 ``WQ_UNBOUND``
   排队到非绑定wq的工作项由特殊的工作者池提供服务,这些工作者不
   绑定在任何特定的CPU上。这使得wq表现得像一个简单的执行环境提
@@ -184,25 +202,21 @@ workqueue将自动创建与属性相匹配的后备工作者池。调节并发
 --------------
 
 ``@max_active`` 决定了每个CPU可以分配给wq的工作项的最大执行上
-下文数量。例如,如果 ``@max_active为16`` ,每个CPU最多可以同
-时执行16个wq的工作项。
+下文数量。例如,如果 ``@max_active`` 为16 ,每个CPU最多可以同
+时执行16个wq的工作项。它总是每CPU属性,即便对于未绑定 wq。
 
-目前,对于一个绑定的wq, ``@max_active`` 的最大限制是512,当指
-定为0时使用的默认值是256。对于非绑定的wq,其限制是512和
-4 * ``num_possible_cpus()`` 中的较高值。这些值被选得足够高,所
-以它们不是限制性因素,同时会在失控情况下提供保护。
+``@max_active`` 的最大限制是512,当指定为0时使用的默认值是256。
+这些值被选得足够高,所以它们不是限制性因素,同时会在失控情况下提供
+保护。
 
 一个wq的活动工作项的数量通常由wq的用户来调节,更具体地说,是由用
 户在同一时间可以排列多少个工作项来调节。除非有特定的需求来控制活动
 工作项的数量,否则建议指定 为"0"。
 
-一些用户依赖于ST wq的严格执行顺序。 ``@max_active`` 为1和 ``WQ_UNBOUND``
-的组合用来实现这种行为。这种wq上的工作项目总是被排到未绑定的工作池
-中,并且在任何时候都只有一个工作项目处于活动状态,从而实现与ST wq相
-同的排序属性。
-
-在目前的实现中,上述配置只保证了特定NUMA节点内的ST行为。相反,
-``alloc_ordered_workqueue()`` 应该被用来实现全系统的ST行为。
+一些用户依赖于任意时刻最多只有一个工作项被执行,且各工作项被按队列中
+顺序处理带来的严格执行顺序。``@max_active`` 为1和 ``WQ_UNBOUND``
+的组合曾被用来实现这种行为,现在不用了。请使用
+``alloc_ordered_workqueue()`` 。
 
 
 执行场景示例
@@ -285,7 +299,7 @@ And with cmwq with ``@max_active`` >= 3, ::
 * 除非有特殊需要,建议使用0作为@max_active。在大多数使用情
   况下,并发水平通常保持在默认限制之下。
 
-* ä¸\80个wqä½\9c为å\89\8dè¿\9bè¿\9b度ä¿\9dè¯\81ï¼\88WQ_MEM_RECLAIM,冲洗(flush)和工
+* ä¸\80个wqä½\9c为å\89\8dè¿\9bè¿\9b度ä¿\9dè¯\81ï¼\8c``WQ_MEM_RECLAIM`` ,冲洗(flush)和工
   作项属性的域。不涉及内存回收的工作项,不需要作为工作项组的一
   部分被刷新,也不需要任何特殊属性,可以使用系统中的一个wq。使
   用专用wq和系统wq在执行特性上没有区别。
@@ -294,6 +308,337 @@ And with cmwq with ``@max_active`` >= 3, ::
   益的,因为wq操作和工作项执行中的定位水平提高了。
 
 
+亲和性作用域
+============
+
+一个非绑定工作队列根据其亲和性作用域来对CPU进行分组以提高缓存
+局部性。比如如果一个工作队列使用默认的“cache”亲和性作用域,
+它将根据最后一级缓存的边界来分组处理器。这个工作队列上的工作项
+将被分配给一个与发起CPU共用最后级缓存的处理器上的工作者。根据
+``affinity_strict`` 的设置,工作者在启动后可能被允许移出
+所在作用域,也可能不被允许。
+
+工作队列目前支持以下亲和性作用域。
+
+``default``
+  使用模块参数 ``workqueue.default_affinity_scope`` 指定
+  的作用域,该参数总是会被设为以下作用域中的一个。
+
+``cpu``
+  CPU不被分组。一个CPU上发起的工作项会被同一CPU上的工作者执行。
+  这使非绑定工作队列表现得像是不含并发管理的每CPU工作队列。
+
+``smt``
+  CPU被按SMT边界分组。这通常意味着每个物理CPU核上的各逻辑CPU会
+  被分进同一组。
+
+``cache``
+  CPU被按缓存边界分组。采用哪个缓存边界由架构代码决定。很多情况
+  下会使用L3。这是默认的亲和性作用域。
+
+``numa``
+  CPU被按NUMA边界分组。
+
+``system``
+  所有CPU被放在同一组。工作队列不尝试在临近发起CPU的CPU上运行
+  工作项。
+
+默认的亲和性作用域可以被模块参数 ``workqueue.default_affinity_scope``
+修改,特定工作队列的亲和性作用域可以通过 ``apply_workqueue_attrs()``
+被更改。
+
+如果设置了 ``WQ_SYSFS`` ,工作队列会在它的 ``/sys/devices/virtual/workqueue/WQ_NAME/``
+目录中有以下亲和性作用域相关的接口文件。
+
+``affinity_scope``
+  读操作以查看当前的亲和性作用域。写操作用于更改设置。
+
+  当前作用域是默认值时,当前生效的作用域也可以被从这个文件中
+  读到(小括号内),例如 ``default (cache)`` 。
+
+``affinity_strict``
+  默认值0表明亲和性作用域不是严格的。当一个工作项开始执行时,
+  工作队列尽量尝试使工作者处于亲和性作用域内,称为遣返。启动后,
+  调度器可以自由地将工作者调度到系统中任意它认为合适的地方去。
+  这使得在保留使用其他CPU(如果必需且有可用)能力的同时,
+  还能从作用域局部性上获益。
+
+  如果设置为1,作用域内的所有工作者将被保证总是处于作用域内。
+  这在跨亲和性作用域会导致如功耗、负载隔离等方面的潜在影响时
+  会有用。严格的NUMA作用域也可用于和旧版内核中工作队列的行为
+  保持一致。
+
+
+亲和性作用域与性能
+==================
+
+如果非绑定工作队列的行为对绝大多数使用场景来说都是最优的,
+不需要更多调节,就完美了。很不幸,在当前内核中,重度使用
+工作队列时,需要在局部性和利用率间显式地作一个明显的权衡。
+
+更高的局部性带来更高效率,也就是相同数量的CPU周期内可以做
+更多工作。然而,如果发起者没能将工作项充分地分散在亲和性
+作用域间,更高的局部性也可能带来更低的整体系统利用率。以下
+dm-crypt 的性能测试清楚地阐明了这一取舍。
+
+测试运行在一个12核24线程、4个L3缓存的处理器(AMD Ryzen
+9 3900x)上。为保持一致性,关闭CPU超频。 ``/dev/dm-0``
+是NVME SSD(三星 990 PRO)上创建,用 ``cryptsetup``
+以默认配置打开的一个 dm-crypt 设备。
+
+
+场景 1: 机器上遍布着有充足的发起者和工作量
+------------------------------------------
+
+使用命令:::
+
+  $ fio --filename=/dev/dm-0 --direct=1 --rw=randrw --bs=32k --ioengine=libaio \
+    --iodepth=64 --runtime=60 --numjobs=24 --time_based --group_reporting \
+    --name=iops-test-job --verify=sha512
+
+这里有24个发起者,每个同时发起64个IO。 ``--verify=sha512``
+使得 ``fio`` 每次生成和读回内容受发起者和 ``kcryptd``
+间的执行局部性影响。下面是基于不同 ``kcryptd`` 的亲和性
+作用域设置,各经过五次测试得到的读取带宽和CPU利用率数据。
+
+.. list-table::
+   :widths: 16 20 20
+   :header-rows: 1
+
+   * - 亲和性
+     - 带宽 (MiBps)
+     - CPU利用率(%)
+
+   * - system
+     - 1159.40 ±1.34
+     - 99.31 ±0.02
+
+   * - cache
+     - 1166.40 ±0.89
+     - 99.34 ±0.01
+
+   * - cache (strict)
+     - 1166.00 ±0.71
+     - 99.35 ±0.01
+
+在系统中分布着足够多发起者的情况下,不论严格与否,“cache”
+没有表现得更差。三种配置均使整个机器达到饱和,但由于提高了
+局部性,缓存相关的两种有0.6%的(带宽)提升。
+
+
+场景 2: 更少发起者,足以达到饱和的工作量
+----------------------------------------
+
+使用命令:::
+
+  $ fio --filename=/dev/dm-0 --direct=1 --rw=randrw --bs=32k \
+    --ioengine=libaio --iodepth=64 --runtime=60 --numjobs=8 \
+    --time_based --group_reporting --name=iops-test-job --verify=sha512
+
+与上一个场景唯一的区别是 ``--numjobs=8``。 发起者数量
+减少为三分之一,但仍然有足以使系统达到饱和的工作总量。
+
+.. list-table::
+   :widths: 16 20 20
+   :header-rows: 1
+
+   * - 亲和性
+     - 带宽 (MiBps)
+     - CPU利用率(%)
+
+   * - system
+     - 1155.40 ±0.89
+     - 97.41 ±0.05
+
+   * - cache
+     - 1154.40 ±1.14
+     - 96.15 ±0.09
+
+   * - cache (strict)
+     - 1112.00 ±4.64
+     - 93.26 ±0.35
+
+这里有超过使系统达到饱和所需的工作量。“system”和“cache”
+都接近但并未使机器完全饱和。“cache”消耗更少的CPU但更高的
+效率使其得到和“system”相同的带宽。
+
+八个发起者盘桓在四个L3缓存作用域间仍然允许“cache (strict)”
+几乎使机器饱和,但缺少对工作的保持(不移到空闲处理器上)
+开始带来3.7%的带宽损失。
+
+
+场景 3: 更少发起者,不充足的工作量
+----------------------------------
+
+使用命令:::
+
+  $ fio --filename=/dev/dm-0 --direct=1 --rw=randrw --bs=32k \
+    --ioengine=libaio --iodepth=64 --runtime=60 --numjobs=4 \
+    --time_based --group_reporting --name=iops-test-job --verify=sha512
+
+再次,唯一的区别是 ``--numjobs=4``。由于发起者减少到四个,
+现在没有足以使系统饱和的工作量,带宽变得依赖于完成时延。
+
+.. list-table::
+   :widths: 16 20 20
+   :header-rows: 1
+
+   * - 亲和性
+     - 带宽 (MiBps)
+     - CPU利用率(%)
+
+   * - system
+     - 993.60 ±1.82
+     - 75.49 ±0.06
+
+   * - cache
+     - 973.40 ±1.52
+     - 74.90 ±0.07
+
+   * - cache (strict)
+     - 828.20 ±4.49
+     - 66.84 ±0.29
+
+现在,局部性和利用率间的权衡更清晰了。“cache”展示出相比
+“system”2%的带宽损失,而“cache (strict)”跌到20%。
+
+
+结论和建议
+----------
+
+在以上试验中,虽然一致并且也明显,但“cache”亲和性作用域
+相比“system”的性能优势并不大。然而,这影响是依赖于作用域
+间距离的,在更复杂的处理器拓扑下可能有更明显的影响。
+
+虽然这些情形下缺少工作保持是有坏处的,但比“cache (strict)”
+好多了,而且最大化工作队列利用率的需求也并不常见。因此,
+“cache”是非绑定池的默认亲和性作用域。
+
+* 由于不存在一个适用于大多数场景的选择,对于可能需要消耗
+  大量CPU的工作队列,建议通过 ``apply_workqueue_attrs()``
+  进行(专门)配置,并考虑是否启用 ``WQ_SYSFS``。
+
+* 设置了严格“cpu”亲和性作用域的非绑定工作队列,它的行为与
+  ``WQ_CPU_INTENSIVE`` 每CPU工作队列一样。后者没有真正
+  优势,而前者提供了大幅度的灵活性。
+
+* 亲和性作用域是从Linux v6.5起引入的。为了模拟旧版行为,
+  可以使用严格的“numa”亲和性作用域。
+
+* 不严格的亲和性作用域中,缺少工作保持大概缘于调度器。内核
+  为什么没能维护好大多数场景下的工作保持,把事情作对,还没有
+  理论上的解释。因此,未来调度器的改进可能会使我们不再需要
+  这些调节项。
+
+
+检查配置
+========
+
+使用 tools/workqueue/wq_dump.py(drgn脚本) 来检查未
+绑定CPU的亲和性配置,工作者池,以及工作队列如何映射到池上: ::
+
+  $ tools/workqueue/wq_dump.py
+  Affinity Scopes
+  ===============
+  wq_unbound_cpumask=0000000f
+
+  CPU
+    nr_pods  4
+    pod_cpus [0]=00000001 [1]=00000002 [2]=00000004 [3]=00000008
+    pod_node [0]=0 [1]=0 [2]=1 [3]=1
+    cpu_pod  [0]=0 [1]=1 [2]=2 [3]=3
+
+  SMT
+    nr_pods  4
+    pod_cpus [0]=00000001 [1]=00000002 [2]=00000004 [3]=00000008
+    pod_node [0]=0 [1]=0 [2]=1 [3]=1
+    cpu_pod  [0]=0 [1]=1 [2]=2 [3]=3
+
+  CACHE (default)
+    nr_pods  2
+    pod_cpus [0]=00000003 [1]=0000000c
+    pod_node [0]=0 [1]=1
+    cpu_pod  [0]=0 [1]=0 [2]=1 [3]=1
+
+  NUMA
+    nr_pods  2
+    pod_cpus [0]=00000003 [1]=0000000c
+    pod_node [0]=0 [1]=1
+    cpu_pod  [0]=0 [1]=0 [2]=1 [3]=1
+
+  SYSTEM
+    nr_pods  1
+    pod_cpus [0]=0000000f
+    pod_node [0]=-1
+    cpu_pod  [0]=0 [1]=0 [2]=0 [3]=0
+
+  Worker Pools
+  ============
+  pool[00] ref= 1 nice=  0 idle/workers=  4/  4 cpu=  0
+  pool[01] ref= 1 nice=-20 idle/workers=  2/  2 cpu=  0
+  pool[02] ref= 1 nice=  0 idle/workers=  4/  4 cpu=  1
+  pool[03] ref= 1 nice=-20 idle/workers=  2/  2 cpu=  1
+  pool[04] ref= 1 nice=  0 idle/workers=  4/  4 cpu=  2
+  pool[05] ref= 1 nice=-20 idle/workers=  2/  2 cpu=  2
+  pool[06] ref= 1 nice=  0 idle/workers=  3/  3 cpu=  3
+  pool[07] ref= 1 nice=-20 idle/workers=  2/  2 cpu=  3
+  pool[08] ref=42 nice=  0 idle/workers=  6/  6 cpus=0000000f
+  pool[09] ref=28 nice=  0 idle/workers=  3/  3 cpus=00000003
+  pool[10] ref=28 nice=  0 idle/workers= 17/ 17 cpus=0000000c
+  pool[11] ref= 1 nice=-20 idle/workers=  1/  1 cpus=0000000f
+  pool[12] ref= 2 nice=-20 idle/workers=  1/  1 cpus=00000003
+  pool[13] ref= 2 nice=-20 idle/workers=  1/  1 cpus=0000000c
+
+  Workqueue CPU -> pool
+  =====================
+  [    workqueue \ CPU              0  1  2  3 dfl]
+  events                   percpu   0  2  4  6
+  events_highpri           percpu   1  3  5  7
+  events_long              percpu   0  2  4  6
+  events_unbound           unbound  9  9 10 10  8
+  events_freezable         percpu   0  2  4  6
+  events_power_efficient   percpu   0  2  4  6
+  events_freezable_power_  percpu   0  2  4  6
+  rcu_gp                   percpu   0  2  4  6
+  rcu_par_gp               percpu   0  2  4  6
+  slub_flushwq             percpu   0  2  4  6
+  netns                    ordered  8  8  8  8  8
+  ...
+
+参见命令的帮助消息以获取更多信息。
+
+
+监视
+====
+
+使用 tools/workqueue/wq_monitor.py 来监视工作队列的运行: ::
+
+  $ tools/workqueue/wq_monitor.py events
+                              total  infl  CPUtime  CPUhog CMW/RPR  mayday rescued
+  events                      18545     0      6.1       0       5       -       -
+  events_highpri                  8     0      0.0       0       0       -       -
+  events_long                     3     0      0.0       0       0       -       -
+  events_unbound              38306     0      0.1       -       7       -       -
+  events_freezable                0     0      0.0       0       0       -       -
+  events_power_efficient      29598     0      0.2       0       0       -       -
+  events_freezable_power_        10     0      0.0       0       0       -       -
+  sock_diag_events                0     0      0.0       0       0       -       -
+
+                              total  infl  CPUtime  CPUhog CMW/RPR  mayday rescued
+  events                      18548     0      6.1       0       5       -       -
+  events_highpri                  8     0      0.0       0       0       -       -
+  events_long                     3     0      0.0       0       0       -       -
+  events_unbound              38322     0      0.1       -       7       -       -
+  events_freezable                0     0      0.0       0       0       -       -
+  events_power_efficient      29603     0      0.2       0       0       -       -
+  events_freezable_power_        10     0      0.0       0       0       -       -
+  sock_diag_events                0     0      0.0       0       0       -       -
+
+  ...
+
+参见命令的帮助消息以获取更多信息。
+
+
 调试
 ====
 
@@ -330,7 +675,6 @@ And with cmwq with ``@max_active`` >= 3, ::
 
 工作队列保证,如果在工作项排队后满足以下条件,则工作项不能重入:
 
-
         1. 工作函数没有被改变。
         2. 没有人将该工作项排到另一个工作队列中。
         3. 该工作项尚未被重新启动。
index c2db3e566b1be80d934da53919ca855c17255c5a..fa900f5beb68bb1d3421b329a70e690dc5976d47 100644 (file)
@@ -22,14 +22,14 @@ Documentation/translations/zh_CN/dev-tools/testing-overview.rst
    sparse
    gcov
    kasan
+   kcov
+   ubsan
+   kmemleak
    gdb-kernel-debugging
 
 Todolist:
 
  - coccinelle
- - kcov
- - ubsan
- - kmemleak
  - kcsan
  - kfence
  - kgdb
diff --git a/Documentation/translations/zh_CN/dev-tools/kcov.rst b/Documentation/translations/zh_CN/dev-tools/kcov.rst
new file mode 100644 (file)
index 0000000..629154d
--- /dev/null
@@ -0,0 +1,359 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/dev-tools/kcov.rst
+:Translator: 刘浩阳 Haoyang Liu <tttturtleruss@hust.edu.cn>
+
+KCOV: 用于模糊测试的代码覆盖率
+==============================
+
+KCOV 以一种适用于覆盖率引导的模糊测试的形式收集和暴露内核代码覆盖率信息。
+一个正在运行的内核的覆盖率数据可以通过 ``kcov`` 调试文件导出。覆盖率的收集是基
+于任务启用的,因此 KCOV 可以精确捕获单个系统调用的覆盖率。
+
+要注意的是 KCOV 不是为了收集尽可能多的覆盖率数据。而是为了收集相对稳定的覆盖率
+,这是系统调用输入的函数。为了完成这个目标,它不收集软硬中断的覆盖率(除非移除
+覆盖率收集被启用,见下文)以及内核中固有的不确定部分的覆盖率(如调度器,锁定)
+
+除了收集代码覆盖率,KCOV 还收集操作数比较的覆盖率。见 "操作数比较收集" 一节
+查看详细信息。
+
+除了从系统调用处理器收集覆盖率数据,KCOV 还从后台内核或软中断任务中执行的内核
+被标注的部分收集覆盖率。见 "远程覆盖率收集" 一节查看详细信息。
+
+先决条件
+--------
+
+KCOV 依赖编译器插桩,要求 GCC 6.1.0 及更高版本或者内核支持的任意版本的 Clang。
+
+收集操作数比较的覆盖率需要 GCC 8+ 或者 Clang。
+
+为了启用 KCOV,需要使用如下参数配置内核::
+
+        CONFIG_KCOV=y
+
+为了启用操作数比较覆盖率的收集,使用如下参数::
+
+    CONFIG_KCOV_ENABLE_COMPARISONS=y
+
+覆盖率数据只会在调试文件系统被挂载后才可以获取::
+
+        mount -t debugfs none /sys/kernel/debug
+
+覆盖率收集
+----------
+
+下面的程序演示了如何使用 KCOV 在一个测试程序中收集单个系统调用的覆盖率:
+
+.. code-block:: c
+
+    #include <stdio.h>
+    #include <stddef.h>
+    #include <stdint.h>
+    #include <stdlib.h>
+    #include <sys/types.h>
+    #include <sys/stat.h>
+    #include <sys/ioctl.h>
+    #include <sys/mman.h>
+    #include <unistd.h>
+    #include <fcntl.h>
+    #include <linux/types.h>
+
+    #define KCOV_INIT_TRACE                    _IOR('c', 1, unsigned long)
+    #define KCOV_ENABLE                        _IO('c', 100)
+    #define KCOV_DISABLE                       _IO('c', 101)
+    #define COVER_SIZE                 (64<<10)
+
+    #define KCOV_TRACE_PC  0
+    #define KCOV_TRACE_CMP 1
+
+    int main(int argc, char **argv)
+    {
+       int fd;
+       unsigned long *cover, n, i;
+
+       /* 单个文件描述符允许
+        * 在单线程上收集覆盖率。
+        */
+       fd = open("/sys/kernel/debug/kcov", O_RDWR);
+       if (fd == -1)
+               perror("open"), exit(1);
+       /* 设置跟踪模式和跟踪大小。 */
+       if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
+               perror("ioctl"), exit(1);
+       /* 映射内核空间和用户空间共享的缓冲区。 */
+       cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
+                                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if ((void*)cover == MAP_FAILED)
+               perror("mmap"), exit(1);
+       /* 在当前线程中启用覆盖率收集。 */
+       if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_PC))
+               perror("ioctl"), exit(1);
+       /* 在调用 ioctl() 之后重置覆盖率。 */
+       __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
+       /* 调用目标系统调用。 */
+       read(-1, NULL, 0);
+       /* 读取收集到的 PC 的数目。 */
+       n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
+       for (i = 0; i < n; i++)
+               printf("0x%lx\n", cover[i + 1]);
+       /* 在当前线程上禁用覆盖率收集。在这之后
+        * 可以在其他线程上收集覆盖率
+        */
+       if (ioctl(fd, KCOV_DISABLE, 0))
+               perror("ioctl"), exit(1);
+       /* 释放资源 */
+       if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
+               perror("munmap"), exit(1);
+       if (close(fd))
+               perror("close"), exit(1);
+       return 0;
+    }
+
+在使用 ``addr2line`` 传输后,程序输出应该如下所示::
+
+    SyS_read
+    fs/read_write.c:562
+    __fdget_pos
+    fs/file.c:774
+    __fget_light
+    fs/file.c:746
+    __fget_light
+    fs/file.c:750
+    __fget_light
+    fs/file.c:760
+    __fdget_pos
+    fs/file.c:784
+    SyS_read
+    fs/read_write.c:562
+
+如果一个程序需要从多个线程收集覆盖率(独立地)。那么每个线程都需要单独打开
+``/sys/kernel/debug/kcov``。
+
+接口的细粒度允许高效的创建测试进程。即,一个父进程打开了
+``/sys/kernel/debug/kcov``,启用了追踪模式,映射了覆盖率缓冲区,然后在一个循
+环中创建了子进程。这个子进程只需要启用覆盖率收集即可(当一个线程退出时将自动禁
+用覆盖率收集)。
+
+操作数比较收集
+--------------
+
+操作数比较收集和覆盖率收集类似:
+
+.. code-block:: c
+
+    /* 包含和上文一样的头文件和宏定义。 */
+
+    /* 每次记录的 64 位字的数量。 */
+    #define KCOV_WORDS_PER_CMP 4
+
+    /*
+     * 收集的比较种类的格式。
+     *
+     * 0 比特表示是否是一个编译时常量。
+     * 1 & 2 比特包含参数大小的 log2 值,最大 8 字节。
+     */
+
+    #define KCOV_CMP_CONST          (1 << 0)
+    #define KCOV_CMP_SIZE(n)        ((n) << 1)
+    #define KCOV_CMP_MASK           KCOV_CMP_SIZE(3)
+
+    int main(int argc, char **argv)
+    {
+       int fd;
+       uint64_t *cover, type, arg1, arg2, is_const, size;
+       unsigned long n, i;
+
+       fd = open("/sys/kernel/debug/kcov", O_RDWR);
+       if (fd == -1)
+               perror("open"), exit(1);
+       if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
+               perror("ioctl"), exit(1);
+       /*
+       * 注意缓冲区指针的类型是 uint64_t*,因为所有的
+       * 比较操作数都被提升为 uint64_t 类型。
+       */
+       cover = (uint64_t *)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
+                                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if ((void*)cover == MAP_FAILED)
+               perror("mmap"), exit(1);
+       /* 注意这里是 KCOV_TRACE_CMP 而不是 KCOV_TRACE_PC。 */
+       if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_CMP))
+               perror("ioctl"), exit(1);
+       __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
+       read(-1, NULL, 0);
+       /* 读取收集到的比较操作数的数量。 */
+       n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
+       for (i = 0; i < n; i++) {
+               uint64_t ip;
+
+               type = cover[i * KCOV_WORDS_PER_CMP + 1];
+               /* arg1 和 arg2 - 比较的两个操作数。 */
+               arg1 = cover[i * KCOV_WORDS_PER_CMP + 2];
+               arg2 = cover[i * KCOV_WORDS_PER_CMP + 3];
+               /* ip - 调用者的地址。 */
+               ip = cover[i * KCOV_WORDS_PER_CMP + 4];
+               /* 操作数的大小。 */
+               size = 1 << ((type & KCOV_CMP_MASK) >> 1);
+               /* is_const - 当操作数是一个编译时常量时为真。*/
+               is_const = type & KCOV_CMP_CONST;
+               printf("ip: 0x%lx type: 0x%lx, arg1: 0x%lx, arg2: 0x%lx, "
+                       "size: %lu, %s\n",
+                       ip, type, arg1, arg2, size,
+               is_const ? "const" : "non-const");
+       }
+       if (ioctl(fd, KCOV_DISABLE, 0))
+               perror("ioctl"), exit(1);
+       /* 释放资源。 */
+       if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
+               perror("munmap"), exit(1);
+       if (close(fd))
+               perror("close"), exit(1);
+       return 0;
+    }
+
+注意 KCOV 的模式(代码覆盖率收集或操作数比较收集)是互斥的。
+
+远程覆盖率收集
+--------------
+
+除了从用户空间进程发布的系统调用句柄收集覆盖率数据以外,KCOV 也可以从部分在其
+他上下文中执行的内核中收集覆盖率 - 称为“远程”覆盖率。
+
+使用 KCOV 收集远程覆盖率要求:
+
+1. 修改内核源码并使用 ``kcov_remote_start`` 和 ``kcov_remote_stop`` 来标注要收集
+   覆盖率的代码片段。
+
+2. 在用户空间的收集覆盖率的进程应使用 ``KCOV_REMOTE_ENABLE`` 而不是 ``KCOV_ENABLE``。
+
+``kcov_remote_start`` 和 ``kcov_remote_stop`` 的标注以及 ``KCOV_REMOTE_ENABLE``
+ioctl 都接受可以识别特定覆盖率收集片段的句柄。句柄的使用方式取决于匹配代码片段执
+行的上下文。
+
+KCOV 支持在如下上下文中收集远程覆盖率:
+
+1. 全局内核后台任务。这些任务是内核启动时创建的数量有限的实例(如,每一个
+   USB HCD 产生一个 USB ``hub_event`` 工作器)。
+
+2. 局部内核后台任务。这些任务通常是由于用户空间进程与某些内核接口进行交互时产
+   生的,并且通常在进程退出时会被停止(如,vhost 工作器)。
+
+3. 软中断。
+
+对于 #1 和 #3,必须选择一个独特的全局句柄并将其传递给对应的
+``kcov_remote_start`` 调用。一个用户空间进程必须将该句柄存储在
+``kcov_remote_arg`` 结构体的 ``handle`` 数组字段中并将其传递给
+``KCOV_REMOTE_ENABLE``。这会将使用的 KCOV 设备附加到由此句柄引用的代码片段。多个全局
+句柄标识的不同代码片段可以一次性传递。
+
+对于 #2,用户空间进程必须通过 ``kcov_remote_arg`` 结构体的 ``common_handle`` 字段
+传递一个非零句柄。这个通用句柄将会被保存在当前 ``task_struct`` 结构体的
+``kcov_handle`` 字段中并且需要通过自定义内核代码的修改来传递给新创建的本地任务
+。这些任务需要在 ``kcov_remote_start`` 和 ``kcov_remote_stop`` 标注中依次使用传递过来的
+句柄。
+
+KCOV 对全局句柄和通用句柄均遵循一个预定义的格式。每一个句柄都是一个 ``u64`` 整形
+。当前,只有最高位和低四位字节被使用。第 4-7 字节是保留位并且值必须为 0。
+
+对于全局句柄,最高位的字节表示该句柄属于的子系统的标识。比如,KCOV 使用 ``1``
+表示 USB 子系统类型。全局句柄的低 4 字节表示子系统中任务实例的标识。比如,每一
+个 ``hub_event`` 工作器使用 USB 总线号作为任务实例的标识。
+
+对于通用句柄,使用一个保留值 ``0`` 作为子系统标识,因为这些句柄不属于一个特定
+的子系统。通用句柄的低 4 字节用于识别有用户进程生成的所有本地句柄的集合实例,
+该进程将通用句柄传递给 ``KCOV_REMOTE_ENABLE``。
+
+实际上,如果只从系统中的单个用户空间进程收集覆盖率,那么可以使用任意值作为通用
+句柄的实例标识。然而,如果通用句柄被多个用户空间进程使用,每个进程必须使用唯一
+的实例标识。一个选择是使用进程标识作为通用句柄实例的标识。
+
+下面的程序演示了如何使用 KCOV 从一个由进程产生的本地任务和处理 USB 总线的全局
+任务 #1 收集覆盖率:
+
+.. code-block:: c
+
+    /* 包含和上文一样的头文件和宏定义。 */
+
+    struct kcov_remote_arg {
+       __u32           trace_mode;
+       __u32           area_size;
+       __u32           num_handles;
+       __aligned_u64   common_handle;
+       __aligned_u64   handles[0];
+    };
+
+    #define KCOV_INIT_TRACE                    _IOR('c', 1, unsigned long)
+    #define KCOV_DISABLE                       _IO('c', 101)
+    #define KCOV_REMOTE_ENABLE         _IOW('c', 102, struct kcov_remote_arg)
+
+    #define COVER_SIZE (64 << 10)
+
+    #define KCOV_TRACE_PC      0
+
+    #define KCOV_SUBSYSTEM_COMMON      (0x00ull << 56)
+    #define KCOV_SUBSYSTEM_USB (0x01ull << 56)
+
+    #define KCOV_SUBSYSTEM_MASK        (0xffull << 56)
+    #define KCOV_INSTANCE_MASK (0xffffffffull)
+
+    static inline __u64 kcov_remote_handle(__u64 subsys, __u64 inst)
+    {
+       if (subsys & ~KCOV_SUBSYSTEM_MASK || inst & ~KCOV_INSTANCE_MASK)
+               return 0;
+       return subsys | inst;
+    }
+
+    #define KCOV_COMMON_ID     0x42
+    #define KCOV_USB_BUS_NUM   1
+
+    int main(int argc, char **argv)
+    {
+       int fd;
+       unsigned long *cover, n, i;
+       struct kcov_remote_arg *arg;
+
+       fd = open("/sys/kernel/debug/kcov", O_RDWR);
+       if (fd == -1)
+               perror("open"), exit(1);
+       if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
+               perror("ioctl"), exit(1);
+       cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
+                                    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+       if ((void*)cover == MAP_FAILED)
+               perror("mmap"), exit(1);
+
+       /* 通过通用句柄和 USB 总线 #1 启用代码覆盖率收集。 */
+       arg = calloc(1, sizeof(*arg) + sizeof(uint64_t));
+       if (!arg)
+               perror("calloc"), exit(1);
+       arg->trace_mode = KCOV_TRACE_PC;
+       arg->area_size = COVER_SIZE;
+       arg->num_handles = 1;
+       arg->common_handle = kcov_remote_handle(KCOV_SUBSYSTEM_COMMON,
+                                                       KCOV_COMMON_ID);
+       arg->handles[0] = kcov_remote_handle(KCOV_SUBSYSTEM_USB,
+                                               KCOV_USB_BUS_NUM);
+       if (ioctl(fd, KCOV_REMOTE_ENABLE, arg))
+               perror("ioctl"), free(arg), exit(1);
+       free(arg);
+
+       /*
+        * 在这里用户需要触发执行一个内核代码段
+        * 该代码段要么使用通用句柄标识
+        * 要么触发了一些 USB 总线 #1 上的一些活动。
+        */
+       sleep(2);
+
+       n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
+       for (i = 0; i < n; i++)
+               printf("0x%lx\n", cover[i + 1]);
+       if (ioctl(fd, KCOV_DISABLE, 0))
+               perror("ioctl"), exit(1);
+       if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
+               perror("munmap"), exit(1);
+       if (close(fd))
+               perror("close"), exit(1);
+       return 0;
+    }
diff --git a/Documentation/translations/zh_CN/dev-tools/kmemleak.rst b/Documentation/translations/zh_CN/dev-tools/kmemleak.rst
new file mode 100644 (file)
index 0000000..d248c84
--- /dev/null
@@ -0,0 +1,229 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/dev-tools/kmemleak.rst
+:Translator: 刘浩阳 Haoyang Liu <tttturtleruss@hust.edu.cn>
+
+内核内存泄露检测器
+==================
+
+Kmemleak 提供了一个类似 `可追踪的垃圾收集器 <https://en.wikipedia.org/wiki/Tra
+cing_garbage_collection>`_ 的方法来检测可能的内核内存泄漏,不同的是孤立对象不会
+被释放,而是仅通过 /sys/kernel/debug/kmemleak 报告。Valgrind 工具
+(``memcheck --leak-check``)使用了一种相似的方法来检测用户空间应用中的内存泄
+露。
+
+用法
+----
+
+"Kernel hacking" 中的 CONFIG_DEBUG_KMEMLEAK 必须被启用。一个内核线程每10分钟
+(默认情况下)扫描一次内存,并且打印出新发现的未被引用的对象个数。
+如果 ``debugfs`` 没有挂载,则执行::
+
+   # mount -t debugfs nodev /sys/kernel/debug/
+
+显示所有扫描出的可能的内存泄漏的细节信息::
+
+   # cat /sys/kernel/debug/kmemleak
+
+启动一次中等程度的内存扫描::
+
+   # echo scan > /sys/kernel/debug/kmemleak
+
+清空当前所有可能的内存泄露列表::
+
+   # echo clear > /sys/kernel/debug/kmemleak
+
+当再次读取 ``/sys/kernel/debug/kmemleak`` 文件时,将会输出自上次扫描以来检测到的
+新的内存泄露。
+
+注意,孤立目标是通过被分配时间来排序的,列表开始的对象可能会导致后续的对象都被
+识别为孤立对象。
+
+可以通过写入 ``/sys/kernel/debug/kmemleak`` 文件在运行时修改内存扫描参数。下面是
+支持的参数:
+
+
+* off
+    禁用 kmemleak(不可逆)
+* stack=on
+    开启任务栈扫描(默认)
+* stack=off
+    禁用任务栈扫描
+* scan=on
+    开启自动内存扫描线程(默认)
+* scan=off
+    关闭自动内存扫描线程
+* scan=<secs>;
+    设定自动内存扫描间隔,以秒为单位(默认值为 600,设置为 0 表示停
+    止自动扫描)
+* scan
+    触发一次内存扫描
+* clear
+    通过标记所有当前已报告的未被引用对象为灰,从而清空当前可能的内存泄露列
+    表;如果 kmemleak 被禁用,则释放所有 kmemleak 对象,。
+* dump=<addr>
+    输出存储在 <addr> 中的对象信息
+
+可以通过在内核命令行中传递 ``kmemleak=off`` 参数从而在启动时禁用 Kmemleak。
+
+在 kmemleak 初始化之前就可能会有内存分配或释放,这些操作被存储在一个早期日志缓
+冲区中。缓冲区的大小通过 CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE 选项配置。
+
+如果 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 被启用,则 kmemleak 默认被禁用。在内核命
+令行中传递 ``kmemleak=on`` 参数来开启这个功能。
+
+如果出现 "Error while writing to stdout" 或 "write_loop: Invalid argument" 这样
+的错误,请确认 kmemleak 被正确启用。
+
+基础算法
+--------
+
+通过 :c:func:`kmalloc`, :c:func:`vmalloc`, :c:func:`kmem_cache_alloc` 以及同类
+函数均被跟踪,指针,包括一些额外的信息如大小和栈追踪等,都被存储在红黑树中。
+对应的释放函数调用也被追踪,并从 kmemleak 数据结构中移除相应指针。
+
+对于一个已分配的内存块,如果通过扫描内存(包括保存寄存器)没有发现任何指针指向
+它的起始地址或者其中的任何位置,则认为这块内存是孤立的。这意味着内核无法将该内
+存块的地址传递给一个释放内存函数,这块内存便被认为泄露了。
+
+扫描算法步骤:
+
+   1. 标记所有对象为白色(最后剩下的白色对象被认为是孤立的)
+   2. 从数据节和栈开始扫描内存,检测每个值是否是红黑树中存储的地址。如果一个指向
+      白色对象的指针被检测到,则将该对象标记为灰色。
+   3. 扫描灰色对象引用的其他对象(有些白色对象可能会变为灰色并被添加到灰名单末尾
+      )直到灰名单为空。
+   4. 剩余的白色对象就被认为是孤立的并通过 /sys/kernel/debug/kmemleak 报告。
+
+有些指向已分配的内存块的指针存储在内核内部的数据结构中,它们不能被检测为孤立。
+为了避免这种情况,kmemleak 也存储了指向需要被查找的内存块范围内的任意地址的地址
+数量,如此一来这些内存便不会被认为泄露。一个例子是 __vmalloc()。
+
+用 kmemleak 测试特定部分
+------------------------
+
+在初始化启动阶段 /sys/kernel/debug/kmemleak 的输出可能会很多,这也可能是你在开发
+时编写的漏洞百出的代码导致的。为了解决这种情况你可以使用 'clear' 命令来清除
+/sys/kernel/debug/kmemleak 输出的所有的未引用对象。在执行 'clear' 后执行 'scan'
+可以发现新的未引用对象,这将会有利你测试代码的特定部分。
+
+为了用一个空的 kmemleak 测试一个特定部分,执行::
+
+   # echo clear > /sys/kernel/debug/kmemleak
+   ... 测试你的内核或者模块 ...
+   # echo scan > /sys/kernel/debug/kmemleak
+
+然后像平常一样获得报告::
+
+   # cat /sys/kernel/debug/kmemleak
+
+释放 kmemleak 内核对象
+----------------------
+
+为了允许访问先前发现的内存泄露,当用户禁用或发生致命错误导致 kmemleak
+被禁用时,内核中的 kmemleak 对象不会被释放。这些对象可能会占用很大
+一部分物理内存。
+
+在这种情况下,你可以用如下命令回收这些内存::
+
+   # echo clear > /sys/kernel/debug/kmemleak
+
+Kmemleak API
+------------
+
+在 include/linux/kmemleak.h 头文件中查看函数原型:
+
+- ``kmemleak_init`` - 初始化 kmemleak
+- ``kmemleak_alloc`` - 通知一个内存块的分配
+- ``kmemleak_alloc_percpu`` - 通知一个 percpu 类型的内存分配
+- ``kmemleak_vmalloc`` - 通知一个使用 vmalloc() 的内存分配
+- ``kmemleak_free`` - 通知一个内存块的释放
+- ``kmemleak_free_part`` - 通知一个部分的内存释放
+- ``kmemleak_free_percpu`` - 通知一个 percpu 类型的内存释放
+- ``kmemleak_update_trace`` - 更新分配对象过程的栈追踪
+- ``kmemleak_not_leak`` - 标记一个对象内存为未泄露的
+- ``kmemleak_ignore`` - 不要扫描或报告某个对象未泄露的
+- ``kmemleak_scan_area`` - 在内存块中添加扫描区域
+- ``kmemleak_no_scan`` - 不扫描某个内存块
+- ``kmemleak_erase`` - 在指针变量中移除某个旧的值
+- ``kmemleak_alloc_recursive`` - 和 kmemleak_alloc 效果相同但会检查是否有递归的
+   内存分配
+- ``kmemleak_free_recursive`` - 和 kmemleak_free 效果相同但会检查是否有递归的
+   内存释放
+
+下列函数使用一个物理地址作为对象指针并且只在地址有一个 lowmem 映射时做出相应的
+行为:
+
+- ``kmemleak_alloc_phys``
+- ``kmemleak_free_part_phys``
+- ``kmemleak_ignore_phys``
+
+解决假阳性/假阴性
+-----------------
+
+假阴性是指由于在内存扫描中有值指向该对象导致 kmemleak 没有报告的实际存在的内存
+泄露(孤立对象)。为了减少假阴性的出现次数,kmemleak 提供了 kmemleak_ignore,
+kmemleak_scan_area,kmemleak_no_scan 和 kmemleak_erase 函数(见上)。
+任务栈也会增加假阴性的数量并且默认不开启对它们的扫描。
+
+假阳性是对象被误报为内存泄露(孤立对象)。对于已知未泄露的对象,kmemleak
+提供了 kmemleak_not_leak 函数。同时 kmemleak_ignore 可以用于标记已知不包含任何
+其他指针的内存块,标记后该内存块不会再被扫描。
+
+一些被报告的泄露仅仅是暂时的,尤其是在 SMP(对称多处理)系统中,因为其指针
+暂存在 CPU 寄存器或栈中。Kmemleak 定义了 MSECS_MIN_AGE(默认值为 1000)
+来表示一个被报告为内存泄露的对象的最小存活时间。
+
+限制和缺点
+----------
+
+主要的缺点是内存分配和释放的性能下降。为了避免其他的损失,只有当
+/sys/kernel/debug/kmemleak 文件被读取时才会进行内存扫描。无论如何,这个工具是出于
+调试的目标,性能表现可能不是最重要的。
+
+为了保持算法简单,kmemleak 寻找指向某个内存块范围中的任何值。这可能会引发假阴性
+现象的出现。但是,最后一个真正的内存泄露也会变得明显。
+
+非指针值的数据是假阴性的另一个来源。在将来的版本中,kmemleak 仅仅会扫
+描已分配结构体中的指针成员。这个特性会解决上述很多的假阴性情况。
+
+Kmemleak 会报告假阳性。这可能发生在某些被分配的内存块不需要被释放的情况下
+(某些 init_call 函数中),指针的计算是通过其他方法而不是常规的 container_of 宏
+或是指针被存储在 kmemleak 没有扫描的地方。
+
+页分配和 ioremap 不会被追踪。
+
+使用 kmemleak-test 测试
+-----------------------
+
+为了检测是否成功启用了 kmemleak,你可以使用一个故意制造内存泄露的模块
+kmemleak-test。设置 CONFIG_SAMPLE_KMEMLEAK 为模块(不能作为内建模块使用)
+并且启动启用了 kmemleak 的内核。加载模块并执行一次扫描::
+
+   # modprobe kmemleak-test
+   # echo scan > /sys/kernel/debug/kmemleak
+
+注意你可能无法立刻或在第一次扫描后得到结果。当 kmemleak 得到结果,将会输出日
+志 ``kmemleak: <count of leaks> new suspected memory leaks`` 。然后通过读取文件
+获取信息::
+
+   # cat /sys/kernel/debug/kmemleak
+   unreferenced object 0xffff89862ca702e8 (size 32):
+     comm "modprobe", pid 2088, jiffies 4294680594 (age 375.486s)
+     hex dump (first 32 bytes):
+       6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b  kkkkkkkkkkkkkkkk
+       6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5  kkkkkkkkkkkkkkk.
+     backtrace:
+       [<00000000e0a73ec7>] 0xffffffffc01d2036
+       [<000000000c5d2a46>] do_one_initcall+0x41/0x1df
+       [<0000000046db7e0a>] do_init_module+0x55/0x200
+       [<00000000542b9814>] load_module+0x203c/0x2480
+       [<00000000c2850256>] __do_sys_finit_module+0xba/0xe0
+       [<000000006564e7ef>] do_syscall_64+0x43/0x110
+       [<000000007c873fa6>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+   ...
+
+用 ``rmmod kmemleak_test`` 移除模块时也会触发
+kmemleak 的结果输出。
diff --git a/Documentation/translations/zh_CN/dev-tools/ubsan.rst b/Documentation/translations/zh_CN/dev-tools/ubsan.rst
new file mode 100644 (file)
index 0000000..2487696
--- /dev/null
@@ -0,0 +1,91 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/dev-tools/ubsan.rst
+:Translator: Dongliang Mu <dzm91@hust.edu.cn>
+
+未定义行为消毒剂 - UBSAN
+====================================
+
+UBSAN是一种动态未定义行为检查工具。
+
+UBSAN使用编译时插桩捕捉未定义行为。编译器在可能导致未定义行为的操作前插入特定
+检测代码。如果检查失败,即检测到未定义行为,__ubsan_handle_* 函数将被调用打印
+错误信息。
+
+GCC自4.9.x [1_] (详见 ``-fsanitize=undefined`` 选项及其子选项)版本后引入这
+一特性。GCC 5.x 版本实现了更多检查器 [2_]。
+
+报告样例
+--------------
+
+::
+
+        ================================================================================
+        UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
+        shift exponent 32 is to large for 32-bit type 'unsigned int'
+        CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc1+ #26
+         0000000000000000 ffffffff82403cc8 ffffffff815e6cd6 0000000000000001
+         ffffffff82403cf8 ffffffff82403ce0 ffffffff8163a5ed 0000000000000020
+         ffffffff82403d78 ffffffff8163ac2b ffffffff815f0001 0000000000000002
+        Call Trace:
+         [<ffffffff815e6cd6>] dump_stack+0x45/0x5f
+         [<ffffffff8163a5ed>] ubsan_epilogue+0xd/0x40
+         [<ffffffff8163ac2b>] __ubsan_handle_shift_out_of_bounds+0xeb/0x130
+         [<ffffffff815f0001>] ? radix_tree_gang_lookup_slot+0x51/0x150
+         [<ffffffff8173c586>] _mix_pool_bytes+0x1e6/0x480
+         [<ffffffff83105653>] ? dmi_walk_early+0x48/0x5c
+         [<ffffffff8173c881>] add_device_randomness+0x61/0x130
+         [<ffffffff83105b35>] ? dmi_save_one_device+0xaa/0xaa
+         [<ffffffff83105653>] dmi_walk_early+0x48/0x5c
+         [<ffffffff831066ae>] dmi_scan_machine+0x278/0x4b4
+         [<ffffffff8111d58a>] ? vprintk_default+0x1a/0x20
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830b2240>] setup_arch+0x405/0xc2c
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830ae053>] start_kernel+0x83/0x49a
+         [<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
+         [<ffffffff830ad386>] x86_64_start_reservations+0x2a/0x2c
+         [<ffffffff830ad4f3>] x86_64_start_kernel+0x16b/0x17a
+        ================================================================================
+
+用法
+-----
+
+使用如下内核配置启用UBSAN::
+
+       CONFIG_UBSAN=y
+
+使用如下内核配置检查整个内核::
+
+        CONFIG_UBSAN_SANITIZE_ALL=y
+
+为了在特定文件或目录启动代码插桩,需要在相应的内核Makefile中添加一行类似内容:
+
+- 单文件(如main.o)::
+
+    UBSAN_SANITIZE_main.o := y
+
+- 一个目录中的所有文件::
+
+    UBSAN_SANITIZE := y
+
+即使设置了``CONFIG_UBSAN_SANITIZE_ALL=y``,为了避免文件被插桩,可使用::
+
+  UBSAN_SANITIZE_main.o := n
+
+与::
+
+  UBSAN_SANITIZE := n
+
+未对齐的内存访问检测可通过开启独立选项 - CONFIG_UBSAN_ALIGNMENT 检测。
+该选项在支持未对齐访问的架构上(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y)
+默认为关闭。该选项仍可通过内核配置启用,但它将产生大量的UBSAN报告。
+
+参考文献
+----------
+
+.. _1: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
+.. _2: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
+.. _3: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
index 6ccec9657cc6037e62b31f920a6ad83f07e25e9f..20b9d4270d1f8350bb328b2d508f5a962777aacb 100644 (file)
@@ -24,8 +24,8 @@
 上的linux-doc邮件列表。
 
 顺便说下,中文文档也需要遵守内核编码风格,风格中中文和英文的主要不同就是中文
-的字符标点占用两个英文字符宽度, 所以,当英文要求不要超过每行100个字符时,
-中文就不要超过50个字符。另外,也要注意'-','=' 等符号与相关标题的对齐。在将
+的字符标点占用两个英文字符宽度,所以,当英文要求不要超过每行100个字符时,
+中文就不要超过50个字符。另外,也要注意'-','='等符号与相关标题的对齐。在将
 补丁提交到社区之前,一定要进行必要的 ``checkpatch.pl`` 检查和编译测试。
 
 与Linux 内核社区一起工作
diff --git a/Documentation/translations/zh_CN/process/cve.rst b/Documentation/translations/zh_CN/process/cve.rst
new file mode 100644 (file)
index 0000000..e39b796
--- /dev/null
@@ -0,0 +1,89 @@
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/process/cve.rst
+:Translator: Dongliang Mu <dzm91@hust.edu.cn>
+
+====
+CVEs
+====
+
+Common Vulnerabilities and Exposure (CVE®) 编号是一种明确的方式来
+识别、定义和登记公开披露的安全漏洞。随着时间的推移,它们在内核项目中的实用性
+已经下降,CVE编号经常以不适当的方式和不适当的原因被分配。因此,内核开发社区
+倾向于避免使用它们。然而,分配CVE与其他形式的安全标识符的持续压力,以及内核
+社区之外的个人和公司的持续滥用,已经清楚地表明内核社区应该控制这些CVE分配。
+
+Linux内核开发团队确实有能力为潜在的Linux内核安全问题分配CVE。CVE的分配
+独立于 :doc:`安全漏洞报送流程</process/security-bugs>`。
+
+所有分配给Linux内核的CVE列表都可以在linux-cve邮件列表的存档中找到,如
+https://lore.kernel.org/linux-cve-announce/ 所示。如果想获得已分配
+CVE的通知,请“订阅”该邮件列表。要获得分配的CVE通知,请订阅该邮件列表:
+`订阅 <https://subspace.kernel.org/subscribing.html>`_。
+
+过程
+=======
+
+作为正常稳定发布过程的一部分,可能存在安全问题的内核更改由负责CVE编号分配
+的开发人员识别,并自动为其分配CVE编号。这些CVE分配会作为经常性的通告经常
+发布在linux-cve-announce邮件列表上。
+
+注意,由于Linux内核在系统中的特殊地位,几乎任何漏洞都可能被利用来危害内核
+的安全性,但是当漏洞被修复后,利用的可能性通常不明显。因此,CVE分配团队过于
+谨慎,并将CVE编号分配给他们识别的任何漏洞修复。这就解释了为什么Linux内核
+团队会发布大量的CVE。
+
+如果CVE分配团队错过了任何用户认为应该分配CVE的特定修复,请发送电子邮件到
+<cve@kernel.org>,那里的团队将与您一起工作。请注意,任何潜在的安全问题
+不应被发送到此邮箱,它仅用于为已发布的内核树中的漏洞修复分配CVE。如果你觉得
+自己发现了一个未修复的安全问题,请按照 :doc:`安全漏洞报送流程
+</process/security-bugs>` 发送到Linux内核社区。
+
+Linux内核不会给未修复的安全问题自动分配CVE;只有在安全修复可用且应用于
+稳定内核树后,CVE分配才会自动发生,并且它将通过安全修复的Git提交编号进行
+跟踪。如果有人希望在提交安全修复之前分配CVE,请联系内核CVE分配团队,从
+他们的一批保留编号中获得相应的CVE编号。
+
+对于目前没有得到稳定与长期维护内核团队积极支持的内核版本中发现的任何问题,
+都不会分配CVEs。当前支持的内核分支列表可以在 https://kernel.org/releases.html
+上找到。
+
+被分配CVE的争论
+=========================
+
+对于为特定内核修改分配的CVE,其争论或修改的权限仅属于受影响子系统的维护者。
+这一原则确保了漏洞报告的高度准确性和可问责性。只有那些具有深厚专业知识和
+对子系统深入了解的维护人员,才能有效评估内核漏洞的有效性和范围,并确定其适当的
+CVE指定策略。在此指定权限之外,任何争论或修改CVE的尝试都可能导致混乱、
+不准确的报告,并最终危及系统。
+
+无效的CVE
+============
+
+如果发现的安全问题存在于仅由某Linux发行版支持的Linux内核中,即安全问题是
+由于Linux发行版所做的更改导致,或者Linux的发行版内核版本不再是Linux内核
+社区支持的内核版本,那么Linux内核CVE团队将不能分配CVE,必须从Linux
+发行版本身请求。
+
+内核CVE分配团队以外的任何团队对Linux内核支持版本分配的CVE都不应被
+视为有效CVE。请通知内核CVE分配团队,以便他们可以通过CNA修复措施使
+这些条目失效。
+
+特定CVE的适用性
+==============================
+
+由于Linux内核可以以许多不同方式使用,外部用户可以通过许多不同方式访问它,或者
+根本没有访问,因此任何特定CVE的适用性取决于Linux用户,而不是内核CVE分配团队。
+请不要与我们联系来尝试确定任何特定CVE的适用性。
+
+此外,由于源代码树非常大,而任何一个系统都只使用源代码树的一小部分,因此任何
+Linux用户都应该意识到,大量分配的CVEs与他们的系统无关。
+
+简而言之,我们不知道您的用例,也不知道您使用的是内核的哪个部分,因此我们无法
+确定特定的CVE是否与您的系统相关。
+
+与往常一样,最好采用所有发布的内核更改,因为它们是由许多社区成员在一个统一的
+整体中一起进行测试的,而不是作为个别的精选更改。还要注意,对于许多安全问题来
+说,整体问题的解决方案并不是在单个更改中找到的,而是在彼此之上的许多修复的总
+和。理想情况下,CVE将被分配给所有问题的所有修复,但有时我们将无法注意到一些
+修复,因此某些修复可能在没有CVE的情况下被采取。
index 3ca02d281be04dd291fc3cbdbd89f3fd33d39741..5c6c8ccdd50de53a1ffb167c2834bef21e3a60e7 100644 (file)
@@ -48,6 +48,7 @@ TODOLIST:
    :maxdepth: 1
 
    embargoed-hardware-issues
+   cve
 
 TODOLIST:
 
index f8978f02057c164c1bf31ea3b1989c412e6083bf..7864107e60a85c58807e401383949eab6608897a 100644 (file)
@@ -333,10 +333,10 @@ Linus 和其他的内核开发者需要阅读和评论你提交的改动。对
 未参与其开发。签署链应当反映补丁传播到维护者并最终传播到Linus所经过的 **真实**
 路径,首个签署指明单个作者的主要作者身份。
 
-何时使用Acked-by:,CC:,和Co-Developed by:
+何时使用Acked-by:,Cc:,和Co-developed-by:
 ------------------------------------------
 
-Singed-off-by: 标签表示签名者参与了补丁的开发,或者他/她在补丁的传递路径中。
+Signed-off-by: 标签表示签名者参与了补丁的开发,或者他/她在补丁的传递路径中。
 
 如果一个人没有直接参与补丁的准备或处理,但希望表示并记录他们对补丁的批准/赞成,
 那么他们可以要求在补丁的变更日志中添加一个Acked-by:。
@@ -358,8 +358,8 @@ Acked-by:不一定表示对整个补丁的确认。例如,如果一个补丁
 Co-developed-by: 声明补丁是由多个开发人员共同创建的;当几个人在一个补丁上工
 作时,它用于给出共同作者(除了From:所给出的作者之外)。因为Co-developed-by:
 表示作者身份,所以每个Co-developed-by:必须紧跟在相关合作作者的签署之后。标准
-签署程序要求Singed-off-by:标签的顺序应尽可能反映补丁的时间历史,无论作者是通
-过From:还是Co-developed-by:表明。值得注意的是,最后一个Singed-off-by:必须是
+签署程序要求Signed-off-by:标签的顺序应尽可能反映补丁的时间历史,无论作者是通
+过From:还是Co-developed-by:表明。值得注意的是,最后一个Signed-off-by:必须是
 提交补丁的开发人员。
 
 注意,如果From:作者也是电子邮件标题的From:行中列出的人,则From:标签是可选的。
index afbd02afec459b644d852fea2fc5356b5a7def29..abd708d48f8259e7b68f7cca7a1b7a0c9679fcc2 100644 (file)
 
 下面是目前可以工作的架构的一般总结。支持程度与 ``MAINTAINERS`` 文件中的``S`` 值相对应:
 
-============  ================  ==============================================
-架构          支持水平          限制因素
-============  ================  ==============================================
-``x86``       Maintained        只有 ``x86_64``
-============  ================  ==============================================
+=============  ================  ==============================================
+架构           支持水平           限制因素
+=============  ================  ==============================================
+``arm64``      Maintained        只有小端序
+``loongarch``  Maintained        \-
+``riscv``      Maintained        只有 ``riscv64``
+``um``         Maintained        只有 ``x86_64``
+``x86``        Maintained        只有 ``x86_64``
+=============  ================  ==============================================
index 6c0bdbbc5a2a4d38e0d990360aa529577d04d89d..419143b938edbd22ce567c357f7c03671350b46f 100644 (file)
@@ -157,6 +157,18 @@ https://commonmark.org/help/
 
        https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
 
+此外,内核支持通过在链接目标前添加 ``srctree/`` 来创建相对于源代码树的链接。例如:
+
+.. code-block:: rust
+
+       //! C header: [`include/linux/printk.h`](srctree/include/linux/printk.h)
+
+或者:
+
+.. code-block:: rust
+
+       /// [`struct mutex`]: srctree/include/linux/mutex.h
+
 
 命名
 ----
index 6b91dfe1834abf13afbb00f05d1e48a6317717d4..251f6ee2bb443532d48e4681bec6959bfdb67f80 100644 (file)
@@ -32,7 +32,7 @@ Rust内核代码使用其内置的文档生成器 ``rustdoc`` 进行记录。
 
 要在你的网络浏览器中本地阅读该文档,请运行如::
 
-       xdg-open rust/doc/kernel/index.html
+       xdg-open Documentation/output/rust/rustdoc/kernel/index.html
 
 要了解如何编写文档,请看 coding-guidelines.rst 。
 
index a4b8e8a50a89b98f1bd10ba0eed8fb9481a58e15..8616556ae4d790a96aa9b78104b7512ca6914ebb 100644 (file)
@@ -37,13 +37,18 @@ rustc
 需要一个特定版本的Rust编译器。较新的版本可能会也可能不会工作,因为就目前而言,内核依赖
 于一些不稳定的Rust特性。
 
-如果使用的是 ``rustup`` ,请进入检出的源代码目录并运行::
+如果使用的是 ``rustup`` ,请进入内核编译目录(或者用 ``--path=<build-dir>`` 参数
+来 ``设置`` sub-command)并运行::
 
        rustup override set $(scripts/min-tool-version.sh rustc)
 
-或者从以下网址获取一个独立的安装程序或安装 ``rustup`` :
++这将配置你的工作目录使用正确版本的 ``rustc``,而不影响你的默认工具链。
 
-       https://www.rust-lang.org
+请注意覆盖应用当前的工作目录(和它的子目录)。
+
+如果你使用 ``rustup``, 可以从下面的链接拉取一个单独的安装程序:
+
+       https://forge.rust-lang.org/infra/other-installation-methods.html#standalone
 
 
 Rust标准库源代码
@@ -57,21 +62,23 @@ Rust标准库的源代码是必需的,因为构建系统会交叉编译 ``core
 
 这些组件是按工具链安装的,因此以后升级Rust编译器版本需要重新添加组件。
 
-否则,如果使用独立的安装程序,可以将Rust仓库克隆到工具链的安装文件夹中::
+否则,如果使用独立的安装程序,可以将Rust源码树下载到安装工具链的文件夹中::
 
-       git clone --recurse-submodules \
-               --branch $(scripts/min-tool-version.sh rustc) \
-               https://github.com/rust-lang/rust \
-               $(rustc --print sysroot)/lib/rustlib/src/rust
+       curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" |
+               tar -xzf - -C "$(rustc --print sysroot)/lib" \
+               "rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \
+               --strip-components=3
 
-在这种情况下,以后升级Rust编译器版本需要手动更新这个克隆的仓库。
+在这种情况下,以后升级Rust编译器版本需要手动更新这个源代码树(这可以通过移除
+``$(rustc --print sysroot)/lib/rustlib/src/rust`` ,然后重新执行上
+面的命令做到)。
 
 
 libclang
 ********
 
 ``bindgen`` 使用 ``libclang`` (LLVM的一部分)来理解内核中的C代码,这意味着需要安
-装LLVM;同在开启 ``CC=clang`` 或 ``LLVM=1`` 时编译内核一样。
+装LLVM;同在开启``LLVM=1`` 时编译内核一样。
 
 Linux发行版中可能会有合适的包,所以最好先检查一下。
 
@@ -94,7 +101,20 @@ bindgen
 
 通过以下方式安装它(注意,这将从源码下载并构建该工具)::
 
-       cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen
+       cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
+
+``bindgen`` 需要找到合适的 ``libclang`` 才能工作。如果没有找到(或者找到的
+``libclang`` 与应该使用的 ``libclang`` 不同),则可以使用 ``clang-sys``
+理解的环境变量(Rust绑定创建的 ``bindgen`` 用来访问 ``libclang``):
+
+
+* ``LLVM_CONFIG_PATH`` 可以指向一个 ``llvm-config`` 可执行文件。
+
+* 或者 ``LIBCLANG_PATH`` 可以指向 ``libclang`` 共享库或包含它的目录。
+
+* 或者 ``CLANG_PATH`` 可以指向 ``clang`` 可执行文件。
+
+详情请参阅 ``clang-sys`` 的文档:
 
 
 开发依赖
@@ -163,7 +183,9 @@ rust-analyzer
 一起使用,以实现语法高亮、补全、转到定义和其他功能。
 
 ``rust-analyzer`` 需要一个配置文件, ``rust-project.json``, 它可以由 ``rust-analyzer``
-Make 目标生成。
+Make 目标生成::
+
+       make LLVM=1 rust-analyzer
 
 
 配置
@@ -189,10 +211,6 @@ Rust支持(CONFIG_RUST)需要在 ``General setup`` 菜单中启用。在其
 
        make LLVM=1
 
-对于不支持完整LLVM工具链的架构,使用::
-
-       make CC=clang
-
 使用GCC对某些配置也是可行的,但目前它是非常试验性的。
 
 
index 43f2e3c5b5148395eeece1b35e7eba8921f90df4..0ecb187753e4c550f7058ff8e7167a6268e39e53 100644 (file)
@@ -31,7 +31,7 @@ Linux內核補丁提交檢查單
 
    c) 使用 ``O=builddir`` 時可以成功編譯
 
-   d) 任何 Doucmentation/ 下的變更都能成功構建且不引入新警告/錯誤。
+   d) 任何 Documentation/ 下的變更都能成功構建且不引入新警告/錯誤。
       用 ``make htmldocs`` 或 ``make pdfdocs`` 檢驗構建情況並修復問題。
 
 3) 通過使用本地交叉編譯工具或其他一些構建設施在多個CPU體系結構上構建。
index 99fa0f2fe6f414e18f86ffffc7a2decd78539b47..f12f2f193f855cfb80b9338442d6d073e57575b7 100644 (file)
@@ -334,10 +334,10 @@ Linus 和其他的內核開發者需要閱讀和評論你提交的改動。對
 未參與其開發。簽署鏈應當反映補丁傳播到維護者並最終傳播到Linus所經過的 **真實**
 路徑,首個簽署指明單個作者的主要作者身份。
 
-何時使用Acked-by:,CC:,和Co-Developed by:
+何時使用Acked-by:,Cc:,和Co-developed-by:
 ------------------------------------------
 
-Singed-off-by: 標籤表示簽名者參與了補丁的開發,或者他/她在補丁的傳遞路徑中。
+Signed-off-by: 標籤表示簽名者參與了補丁的開發,或者他/她在補丁的傳遞路徑中。
 
 如果一個人沒有直接參與補丁的準備或處理,但希望表示並記錄他們對補丁的批准/贊成,
 那麼他們可以要求在補丁的變更日誌中添加一個Acked-by:。
@@ -359,8 +359,8 @@ Acked-by:不一定表示對整個補丁的確認。例如,如果一個補丁
 Co-developed-by: 聲明補丁是由多個開發人員共同創建的;當幾個人在一個補丁上工
 作時,它用於給出共同作者(除了From:所給出的作者之外)。因爲Co-developed-by:
 表示作者身份,所以每個Co-developed-by:必須緊跟在相關合作作者的簽署之後。標準
-簽署程序要求Singed-off-by:標籤的順序應儘可能反映補丁的時間歷史,無論作者是通
-過From:還是Co-developed-by:表明。值得注意的是,最後一個Singed-off-by:必須是
+簽署程序要求Signed-off-by:標籤的順序應儘可能反映補丁的時間歷史,無論作者是通
+過From:還是Co-developed-by:表明。值得注意的是,最後一個Signed-off-by:必須是
 提交補丁的開發人員。
 
 注意,如果From:作者也是電子郵件標題的From:行中列出的人,則From:標籤是可選的。
index f6dc90559341f5aa3debd8592f0da973624238e7..d1f0a56d6c1e30e60c49d7595ecccc67436b2ab3 100644 (file)
@@ -553,7 +553,7 @@ F:  Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
 F:     drivers/input/misc/adxl34x.c
 
 ADXL355 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
-M:     Puranjay Mohan <puranjay12@gmail.com>
+M:     Puranjay Mohan <puranjay@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Supported
 F:     Documentation/devicetree/bindings/iio/accel/adi,adxl355.yaml
@@ -993,7 +993,7 @@ F:  drivers/video/fbdev/geode/
 
 AMD HSMP DRIVER
 M:     Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
-R:     Carlos Bilbao <carlos.bilbao@amd.com>
+R:     Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 L:     platform-driver-x86@vger.kernel.org
 S:     Maintained
 F:     Documentation/arch/x86/amd_hsmp.rst
@@ -2585,12 +2585,8 @@ F:       arch/arm64/boot/dts/qcom/sc7180*
 F:     arch/arm64/boot/dts/qcom/sc7280*
 F:     arch/arm64/boot/dts/qcom/sdm845-cheza*
 
-ARM/QUALCOMM SUPPORT
-M:     Bjorn Andersson <andersson@kernel.org>
-M:     Konrad Dybcio <konrad.dybcio@linaro.org>
+ARM/QUALCOMM MAILING LIST
 L:     linux-arm-msm@vger.kernel.org
-S:     Maintained
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
 F:     Documentation/devicetree/bindings/*/qcom*
 F:     Documentation/devicetree/bindings/soc/qcom/
 F:     arch/arm/boot/dts/qcom/
@@ -2627,6 +2623,33 @@ F:       include/dt-bindings/*/qcom*
 F:     include/linux/*/qcom*
 F:     include/linux/soc/qcom/
 
+ARM/QUALCOMM SUPPORT
+M:     Bjorn Andersson <andersson@kernel.org>
+M:     Konrad Dybcio <konrad.dybcio@linaro.org>
+L:     linux-arm-msm@vger.kernel.org
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
+F:     Documentation/devicetree/bindings/arm/qcom-soc.yaml
+F:     Documentation/devicetree/bindings/arm/qcom.yaml
+F:     Documentation/devicetree/bindings/bus/qcom*
+F:     Documentation/devicetree/bindings/cache/qcom,llcc.yaml
+F:     Documentation/devicetree/bindings/firmware/qcom,scm.yaml
+F:     Documentation/devicetree/bindings/reserved-memory/qcom
+F:     Documentation/devicetree/bindings/soc/qcom/
+F:     arch/arm/boot/dts/qcom/
+F:     arch/arm/configs/qcom_defconfig
+F:     arch/arm/mach-qcom/
+F:     arch/arm64/boot/dts/qcom/
+F:     drivers/bus/qcom*
+F:     drivers/firmware/qcom/
+F:     drivers/soc/qcom/
+F:     include/dt-bindings/arm/qcom,ids.h
+F:     include/dt-bindings/firmware/qcom,scm.h
+F:     include/dt-bindings/soc/qcom*
+F:     include/linux/firmware/qcom
+F:     include/linux/soc/qcom/
+F:     include/soc/qcom/
+
 ARM/RDA MICRO ARCHITECTURE
 M:     Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -3714,7 +3737,7 @@ F:        drivers/iio/imu/bmi323/
 
 BPF JIT for ARM
 M:     Russell King <linux@armlinux.org.uk>
-M:     Puranjay Mohan <puranjay12@gmail.com>
+M:     Puranjay Mohan <puranjay@kernel.org>
 L:     bpf@vger.kernel.org
 S:     Maintained
 F:     arch/arm/net/
@@ -3764,6 +3787,8 @@ X:        arch/riscv/net/bpf_jit_comp64.c
 
 BPF JIT for RISC-V (64-bit)
 M:     Björn Töpel <bjorn@kernel.org>
+R:     Pu Lehui <pulehui@huawei.com>
+R:     Puranjay Mohan <puranjay@kernel.org>
 L:     bpf@vger.kernel.org
 S:     Maintained
 F:     arch/riscv/net/
@@ -4191,7 +4216,6 @@ S:        Supported
 F:     drivers/scsi/bnx2i/
 
 BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
-M:     Ariel Elior <aelior@marvell.com>
 M:     Sudarsana Kalluru <skalluru@marvell.com>
 M:     Manish Chopra <manishc@marvell.com>
 L:     netdev@vger.kernel.org
@@ -5352,7 +5376,7 @@ F:        drivers/usb/atm/cxacru.c
 
 CONFIDENTIAL COMPUTING THREAT MODEL FOR X86 VIRTUALIZATION (SNP/TDX)
 M:     Elena Reshetova <elena.reshetova@intel.com>
-M:     Carlos Bilbao <carlos.bilbao@amd.com>
+M:     Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 S:     Maintained
 F:     Documentation/security/snp-tdx-threat-model.rst
 
@@ -5708,7 +5732,7 @@ Q:        http://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/cxd2820r*
 
 CXGB3 ETHERNET DRIVER (CXGB3)
-M:     Raju Rangoju <rajur@chelsio.com>
+M:     Potnuri Bharat Teja <bharat@chelsio.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.chelsio.com
@@ -5729,7 +5753,7 @@ W:        http://www.chelsio.com
 F:     drivers/crypto/chelsio
 
 CXGB4 ETHERNET DRIVER (CXGB4)
-M:     Raju Rangoju <rajur@chelsio.com>
+M:     Potnuri Bharat Teja <bharat@chelsio.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.chelsio.com
@@ -5758,7 +5782,7 @@ F:        drivers/infiniband/hw/cxgb4/
 F:     include/uapi/rdma/cxgb4-abi.h
 
 CXGB4VF ETHERNET DRIVER (CXGB4VF)
-M:     Raju Rangoju <rajur@chelsio.com>
+M:     Potnuri Bharat Teja <bharat@chelsio.com>
 L:     netdev@vger.kernel.org
 S:     Supported
 W:     http://www.chelsio.com
@@ -6401,6 +6425,7 @@ S:        Maintained
 P:     Documentation/doc-guide/maintainer-profile.rst
 T:     git git://git.lwn.net/linux.git docs-next
 F:     Documentation/
+F:     scripts/check-variable-fonts.sh
 F:     scripts/documentation-file-ref-check
 F:     scripts/kernel-doc
 F:     scripts/sphinx-pre-install
@@ -10602,7 +10627,7 @@ S:      Orphan
 F:     drivers/video/fbdev/imsttfb.c
 
 INDEX OF FURTHER KERNEL DOCUMENTATION
-M:     Carlos Bilbao <carlos.bilbao@amd.com>
+M:     Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 S:     Maintained
 F:     Documentation/process/kernel-docs.rst
 
@@ -12013,6 +12038,15 @@ S:     Maintained
 F:     include/keys/trusted_caam.h
 F:     security/keys/trusted-keys/trusted_caam.c
 
+KEYS-TRUSTED-DCP
+M:     David Gstir <david@sigma-star.at>
+R:     sigma star Kernel Team <upstream+dcp@sigma-star.at>
+L:     linux-integrity@vger.kernel.org
+L:     keyrings@vger.kernel.org
+S:     Supported
+F:     include/keys/trusted_dcp.h
+F:     security/keys/trusted-keys/trusted_dcp.c
+
 KEYS-TRUSTED-TEE
 M:     Sumit Garg <sumit.garg@linaro.org>
 L:     linux-integrity@vger.kernel.org
@@ -12040,6 +12074,7 @@ M:      Mimi Zohar <zohar@linux.ibm.com>
 L:     linux-integrity@vger.kernel.org
 L:     keyrings@vger.kernel.org
 S:     Supported
+W:     https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
 F:     security/integrity/platform_certs
 
 KFENCE
@@ -15160,9 +15195,8 @@ F:      drivers/scsi/myrb.*
 F:     drivers/scsi/myrs.*
 
 MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
-M:     Chris Lee <christopher.lee@cspi.com>
 L:     netdev@vger.kernel.org
-S:     Supported
+S:     Orphan
 W:     https://www.cspi.com/ethernet-products/support/downloads/
 F:     drivers/net/ethernet/myricom/myri10ge/
 
@@ -17990,7 +18024,6 @@ S:      Supported
 F:     drivers/scsi/qedi/
 
 QLOGIC QL4xxx ETHERNET DRIVER
-M:     Ariel Elior <aelior@marvell.com>
 M:     Manish Chopra <manishc@marvell.com>
 L:     netdev@vger.kernel.org
 S:     Supported
@@ -18000,7 +18033,6 @@ F:      include/linux/qed/
 
 QLOGIC QL4xxx RDMA DRIVER
 M:     Michal Kalderon <mkalderon@marvell.com>
-M:     Ariel Elior <aelior@marvell.com>
 L:     linux-rdma@vger.kernel.org
 S:     Supported
 F:     drivers/infiniband/hw/qedr/
@@ -18578,7 +18610,7 @@ F:      tools/testing/selftests/resctrl/
 READ-COPY UPDATE (RCU)
 M:     "Paul E. McKenney" <paulmck@kernel.org>
 M:     Frederic Weisbecker <frederic@kernel.org> (kernel/rcu/tree_nocb.h)
-M:     Neeraj Upadhyay <quic_neeraju@quicinc.com> (kernel/rcu/tasks.h)
+M:     Neeraj Upadhyay <neeraj.upadhyay@kernel.org> (kernel/rcu/tasks.h)
 M:     Joel Fernandes <joel@joelfernandes.org>
 M:     Josh Triplett <josh@joshtriplett.org>
 M:     Boqun Feng <boqun.feng@gmail.com>
@@ -20682,7 +20714,7 @@ Q:      http://patchwork.linuxtv.org/project/linux-media/list/
 F:     drivers/media/dvb-frontends/sp2*
 
 SPANISH DOCUMENTATION
-M:     Carlos Bilbao <carlos.bilbao@amd.com>
+M:     Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
 R:     Avadhut Naik <avadhut.naik@amd.com>
 S:     Maintained
 F:     Documentation/translations/sp_SP/
@@ -20834,6 +20866,13 @@ T:     git git://linuxtv.org/media_tree.git
 F:     Documentation/devicetree/bindings/media/i2c/st,st-mipid02.yaml
 F:     drivers/media/i2c/st-mipid02.c
 
+ST STM32 FIREWALL
+M:     Gatien Chevallier <gatien.chevallier@foss.st.com>
+S:     Maintained
+F:     drivers/bus/stm32_etzpc.c
+F:     drivers/bus/stm32_firewall.c
+F:     drivers/bus/stm32_rifsc.c
+
 ST STM32 I2C/SMBUS DRIVER
 M:     Pierre-Yves MORDRET <pierre-yves.mordret@foss.st.com>
 M:     Alain Volmat <alain.volmat@foss.st.com>
@@ -21476,6 +21515,7 @@ F:      drivers/cpufreq/sc[mp]i-cpufreq.c
 F:     drivers/firmware/arm_scmi/
 F:     drivers/firmware/arm_scpi.c
 F:     drivers/hwmon/scmi-hwmon.c
+F:     drivers/pinctrl/pinctrl-scmi.c
 F:     drivers/pmdomain/arm/
 F:     drivers/powercap/arm_scmi_powercap.c
 F:     drivers/regulator/scmi-regulator.c
@@ -21707,6 +21747,7 @@ F:      Documentation/driver-api/tee.rst
 F:     Documentation/tee/
 F:     Documentation/userspace-api/tee.rst
 F:     drivers/tee/
+F:     include/linux/tee_core.h
 F:     include/linux/tee_drv.h
 F:     include/uapi/linux/tee.h
 
@@ -21918,7 +21959,7 @@ F:      include/linux/soc/ti/ti_sci_inta_msi.h
 F:     include/linux/soc/ti/ti_sci_protocol.h
 
 TEXAS INSTRUMENTS' TMP117 TEMPERATURE SENSOR DRIVER
-M:     Puranjay Mohan <puranjay12@gmail.com>
+M:     Puranjay Mohan <puranjay@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Supported
 F:     Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml
@@ -22411,7 +22452,7 @@ M:      Jarkko Sakkinen <jarkko@kernel.org>
 R:     Jason Gunthorpe <jgg@ziepe.ca>
 L:     linux-integrity@vger.kernel.org
 S:     Maintained
-W:     https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
+W:     https://gitlab.com/jarkkojs/linux-tpmdd-test
 Q:     https://patchwork.kernel.org/project/linux-integrity/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
 F:     Documentation/devicetree/bindings/tpm/
@@ -22500,6 +22541,15 @@ F:     Documentation/ABI/testing/configfs-tsm
 F:     drivers/virt/coco/tsm.c
 F:     include/linux/tsm.h
 
+TRUSTED SERVICES TEE DRIVER
+M:     Balint Dobszay <balint.dobszay@arm.com>
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L:     trusted-services@lists.trustedfirmware.org
+S:     Maintained
+F:     Documentation/tee/ts-tee.rst
+F:     drivers/tee/tstee/
+
 TTY LAYER AND SERIAL DRIVERS
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 M:     Jiri Slaby <jirislaby@kernel.org>
@@ -24459,6 +24509,14 @@ T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/har
 F:     Documentation/admin-guide/LSM/Yama.rst
 F:     security/yama/
 
+YAML NETLINK (YNL)
+M:     Donald Hunter <donald.hunter@gmail.com>
+M:     Jakub Kicinski <kuba@kernel.org>
+F:     Documentation/netlink/
+F:     Documentation/userspace-api/netlink/intro-specs.rst
+F:     Documentation/userspace-api/netlink/specs.rst
+F:     tools/net/ynl/
+
 YEALINK PHONE DRIVER
 M:     Henk Vergonet <Henk.Vergonet@gmail.com>
 L:     usbb2k-api-dev@nongnu.org
index 43b10f3d438cf4f3b8b099340f7cc2c1396ee178..967e97878ecdf660d8b37419fe9fd9a37743a078 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 6
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc5
+EXTRAVERSION =
 NAME = Hurr durr I'ma ninja sloth
 
 # *DOCUMENTATION*
index 65afb1de48b36e843bd665a91df6b33badfd23d1..9f2f3060a6ab14fad2ee0d791a16f17d73067cd4 100644 (file)
@@ -9,6 +9,14 @@
 #
 source "arch/$(SRCARCH)/Kconfig"
 
+config ARCH_CONFIGURES_CPU_MITIGATIONS
+       bool
+
+if !ARCH_CONFIGURES_CPU_MITIGATIONS
+config CPU_MITIGATIONS
+       def_bool y
+endif
+
 menu "General architecture-dependent options"
 
 config ARCH_HAS_SUBPAGE_FAULTS
@@ -55,7 +63,7 @@ config KPROBES
        depends on MODULES
        depends on HAVE_KPROBES
        select KALLSYMS
-       select TASKS_RCU if PREEMPTION
+       select NEED_TASKS_RCU
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
@@ -104,7 +112,7 @@ config STATIC_CALL_SELFTEST
 config OPTPROBES
        def_bool y
        depends on KPROBES && HAVE_OPTPROBES
-       select TASKS_RCU if PREEMPTION
+       select NEED_TASKS_RCU
 
 config KPROBES_ON_FTRACE
        def_bool y
@@ -1609,4 +1617,7 @@ config CC_HAS_SANE_FUNCTION_ALIGNMENT
        # strict alignment always, even with -falign-functions.
        def_bool CC_HAS_MIN_FUNCTION_ALIGNMENT || CC_IS_CLANG
 
+config ARCH_NEED_CMPXCHG_1_EMU
+       bool
+
 endmenu
index 3afd042150f8aff71a1709e9ab3e704a829c3a45..50ff06d5b799c9012dfb07cab9d65e0f2b5b5935 100644 (file)
@@ -10,7 +10,7 @@ config ALPHA
        select ARCH_NO_SG_CHAIN
        select ARCH_USE_CMPXCHG_LOCKREF
        select DMA_OPS if PCI
-       select FORCE_PCI if !ALPHA_JENSEN
+       select FORCE_PCI
        select PCI_DOMAINS if PCI
        select PCI_SYSCALL if PCI
        select HAVE_ASM_MODVERSIONS
@@ -90,22 +90,11 @@ choice
          <http://www.alphalinux.org/>. In summary:
 
          Alcor/Alpha-XLT     AS 600, AS 500, XL-300, XL-366
-         Alpha-XL            XL-233, XL-266
-         AlphaBook1          Alpha laptop
-         Avanti              AS 200, AS 205, AS 250, AS 255, AS 300, AS 400
-         Cabriolet           AlphaPC64, AlphaPCI64
          DP264               DP264 / DS20 / ES40 / DS10 / DS10L
-         EB164               EB164 21164 evaluation board
-         EB64+               EB64+ 21064 evaluation board
-         EB66                EB66 21066 evaluation board
-         EB66+               EB66+ 21066 evaluation board
-         Jensen              DECpc 150, DEC 2000 models 300, 500
          LX164               AlphaPC164-LX
-         Lynx                AS 2100A
          Miata               Personal Workstation 433/500/600 a/au
          Marvel              AlphaServer ES47 / ES80 / GS1280
          Mikasa              AS 1000
-         Noname              AXPpci33, UDB (Multia)
          Noritake            AS 1000A, AS 600A, AS 800
          PC164               AlphaPC164
          Rawhide             AS 1200, AS 4000, AS 4100
@@ -137,27 +126,6 @@ config ALPHA_ALCOR
          all the work required to support an external Bcache and to maintain
          memory coherence when a PCI device DMAs into (or out of) memory.
 
-config ALPHA_XL
-       bool "Alpha-XL"
-       help
-         XL-233 and XL-266-based Alpha systems.
-
-config ALPHA_BOOK1
-       bool "AlphaBook1"
-       help
-         Dec AlphaBook1/Burns Alpha-based laptops.
-
-config ALPHA_AVANTI_CH
-       bool "Avanti"
-
-config ALPHA_CABRIOLET
-       bool "Cabriolet"
-       help
-         Cabriolet AlphaPC64, AlphaPCI64 systems.  Derived from EB64+ but now
-         baby-AT with Flash boot ROM, no on-board SCSI or Ethernet. 3 ISA
-         slots, 4 PCI slots (one pair are on a shared slot), uses plug-in
-         Bcache SIMMs.  Requires power supply with 3.3V output.
-
 config ALPHA_DP264
        bool "DP264"
        help
@@ -165,62 +133,18 @@ config ALPHA_DP264
          API Networks: 264DP, UP2000(+), CS20;
          Compaq: DS10(E,L), XP900, XP1000, DS20(E), ES40.
 
-config ALPHA_EB164
-       bool "EB164"
-       help
-         EB164 21164 evaluation board from DEC.  Uses 21164 and ALCOR.  Has
-         ISA and PCI expansion (3 ISA slots, 2 64-bit PCI slots (one is
-         shared with an ISA slot) and 2 32-bit PCI slots.  Uses plus-in
-         Bcache SIMMs. I/O sub-system provides SuperI/O (2S, 1P, FD), KBD,
-         MOUSE (PS2 style), RTC/NVRAM.  Boot ROM is Flash.  PC-AT-sized
-         motherboard.  Requires power supply with 3.3V output.
-
-config ALPHA_EB64P_CH
-       bool "EB64+"
-
-config ALPHA_EB66
-       bool "EB66"
-       help
-         A Digital DS group board.  Uses 21066 or 21066A.  I/O sub-system is
-         identical to EB64+.  Baby PC-AT size.  Runs from standard PC power
-         supply.  The EB66 schematic was published as a marketing poster
-         advertising the 21066 as "the first microprocessor in the world with
-         embedded PCI".
-
-config ALPHA_EB66P
-       bool "EB66+"
-       help
-         Later variant of the EB66 board.
-
 config ALPHA_EIGER
        bool "Eiger"
        help
          Apparently an obscure OEM single-board computer based on the
          Typhoon/Tsunami chipset family. Information on it is scanty.
 
-config ALPHA_JENSEN
-       bool "Jensen"
-       select HAVE_EISA
-       help
-         DEC PC 150 AXP (aka Jensen): This is a very old Digital system - one
-         of the first-generation Alpha systems. A number of these systems
-         seem to be available on the second- hand market. The Jensen is a
-         floor-standing tower system which originally used a 150MHz 21064 It
-         used programmable logic to interface a 486 EISA I/O bridge to the
-         CPU.
-
 config ALPHA_LX164
        bool "LX164"
        help
          A technical overview of this board is available at
          <http://www.unix-ag.org/Linux-Alpha/Architectures/LX164.html>.
 
-config ALPHA_LYNX
-       bool "Lynx"
-       select HAVE_EISA
-       help
-         AlphaServer 2100A-based systems.
-
 config ALPHA_MARVEL
        bool "Marvel"
        help
@@ -243,9 +167,6 @@ config ALPHA_NAUTILUS
        help
          Alpha systems based on the AMD 751 & ALI 1543C chipsets.
 
-config ALPHA_NONAME_CH
-       bool "Noname"
-
 config ALPHA_NORITAKE
        bool "Noritake"
        select HAVE_EISA
@@ -256,9 +177,6 @@ config ALPHA_NORITAKE
 config ALPHA_PC164
        bool "PC164"
 
-config ALPHA_P2K
-       bool "Platform2000"
-
 config ALPHA_RAWHIDE
        bool "Rawhide"
        select HAVE_EISA
@@ -322,84 +240,18 @@ config ISA_DMA_API
        bool
        default y
 
-config ALPHA_NONAME
-       bool
-       depends on ALPHA_BOOK1 || ALPHA_NONAME_CH
-       default y
-       help
-         The AXPpci33 (aka NoName), is based on the EB66 (includes the Multia
-         UDB).  This design was produced by Digital's Technical OEM (TOEM)
-         group. It uses the 21066 processor running at 166MHz or 233MHz. It
-         is a baby-AT size, and runs from a standard PC power supply. It has
-         5 ISA slots and 3 PCI slots (one pair are a shared slot). There are
-         2 versions, with either PS/2 or large DIN connectors for the
-         keyboard.
-
-config ALPHA_EV4
-       bool
-       depends on ALPHA_JENSEN || (ALPHA_SABLE && !ALPHA_GAMMA) || ALPHA_LYNX || ALPHA_NORITAKE && !ALPHA_PRIMO || ALPHA_MIKASA && !ALPHA_PRIMO || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL || ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
-       default y if !ALPHA_LYNX
-       default y if !ALPHA_EV5
-
-config ALPHA_LCA
-       bool
-       depends on ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
-       default y
-
-config ALPHA_APECS
-       bool
-       depends on !ALPHA_PRIMO && (ALPHA_NORITAKE || ALPHA_MIKASA) || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL
-       default y
-
-config ALPHA_EB64P
-       bool
-       depends on ALPHA_CABRIOLET || ALPHA_EB64P_CH
-       default y
-       help
-         Uses 21064 or 21064A and APECs.  Has ISA and PCI expansion (3 ISA,
-         2 PCI, one pair are on a shared slot). Supports 36-bit DRAM SIMs.
-         ISA bus generated by Intel SaturnI/O PCI-ISA bridge. On-board SCSI
-         (NCR 810 on PCI) Ethernet (Digital 21040), KBD, MOUSE (PS2 style),
-         SuperI/O (2S, 1P, FD), RTC/NVRAM. Boot ROM is EPROM.  PC-AT size.
-         Runs from standard PC power supply.
-
-config ALPHA_EV5
-       bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_LYNX
-       default y if ALPHA_RX164 || ALPHA_RAWHIDE || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_SABLE && ALPHA_GAMMA || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
-
 config ALPHA_CIA
        bool
-       depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
+       depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE || ALPHA_MIKASA || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_ALCOR
        default y
 
 config ALPHA_EV56
-       bool "EV56 CPU (speed >= 366MHz)?" if ALPHA_ALCOR
-       default y if ALPHA_RX164 || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_PC164 || ALPHA_TAKARA
-
-config ALPHA_EV56
-       prompt "EV56 CPU (speed >= 333MHz)?"
-       depends on ALPHA_NORITAKE || ALPHA_PRIMO
-
-config ALPHA_EV56
-       prompt "EV56 CPU (speed >= 400MHz)?"
-       depends on ALPHA_RAWHIDE
-
-config ALPHA_PRIMO
-       bool "EV5 CPU daughtercard (model 5/xxx)?"
-       depends on ALPHA_NORITAKE || ALPHA_MIKASA
-       help
-         Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx.
-
-config ALPHA_GAMMA
-       bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_SABLE
-       depends on ALPHA_SABLE || ALPHA_LYNX
-       default ALPHA_LYNX
-       help
-         Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
+       bool
+       default y if ALPHA_ALCOR || ALPHA_RX164 || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_NORITAKE || ALPHA_MIKASA || ALPHA_RAWHIDE || ALPHA_SABLE
 
 config ALPHA_T2
        bool
-       depends on ALPHA_SABLE || ALPHA_LYNX
+       depends on ALPHA_SABLE
        default y
 
 config ALPHA_PYXIS
@@ -443,15 +295,6 @@ config GENERIC_HWEIGHT
        bool
        default y if !ALPHA_EV67
 
-config ALPHA_AVANTI
-       bool
-       depends on ALPHA_XL || ALPHA_AVANTI_CH
-       default y
-       help
-         Avanti AS 200, AS 205, AS 250, AS 255, AS 300, and AS 400-based
-         Alphas. Info at
-         <http://www.unix-ag.org/Linux-Alpha/Architectures/Avanti.html>.
-
 config ALPHA_BROKEN_IRQ_MASK
        bool
        depends on ALPHA_GENERIC || ALPHA_PC164
@@ -481,9 +324,9 @@ config ALPHA_QEMU
 
 
 config ALPHA_SRM
-       bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
+       bool "Use SRM as bootloader" if ALPHA_PC164 || ALPHA_TAKARA || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS
        depends on TTY
-       default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
+       default y if ALPHA_MIKASA || ALPHA_SABLE || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL
        help
          There are two different types of booting firmware on Alphas: SRM,
          which is command line driven, and ARC, which uses menus and arrow
@@ -509,7 +352,7 @@ config ARCH_MAY_HAVE_PC_FDC
 
 config SMP
        bool "Symmetric multi-processing support"
-       depends on ALPHA_SABLE || ALPHA_LYNX || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
+       depends on ALPHA_SABLE || ALPHA_RAWHIDE || ALPHA_DP264 || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_GENERIC || ALPHA_SHARK || ALPHA_MARVEL
        help
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, say N. If you have a system with more
@@ -545,7 +388,7 @@ config ARCH_SPARSEMEM_ENABLE
 config ALPHA_WTINT
        bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
        default y if ALPHA_QEMU
-       default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
+       default n if ALPHA_EV56
        default n if !ALPHA_SRM && !ALPHA_GENERIC
        default y if SMP
        help
index 45158024085e26faa4d0e51523563758b638ac42..35445ff2e489b235f7e37d699924b78a08f2fd51 100644 (file)
@@ -15,18 +15,14 @@ CHECKFLAGS  += -D__alpha__
 cflags-y       := -pipe -mno-fp-regs -ffixed-8
 cflags-y       += $(call cc-option, -fno-jump-tables)
 
-cpuflags-$(CONFIG_ALPHA_EV4)           := -mcpu=ev4
-cpuflags-$(CONFIG_ALPHA_EV5)           := -mcpu=ev5
 cpuflags-$(CONFIG_ALPHA_EV56)          := -mcpu=ev56
 cpuflags-$(CONFIG_ALPHA_POLARIS)       := -mcpu=pca56
 cpuflags-$(CONFIG_ALPHA_SX164)         := -mcpu=pca56
 cpuflags-$(CONFIG_ALPHA_EV6)           := -mcpu=ev6
 cpuflags-$(CONFIG_ALPHA_EV67)          := -mcpu=ev67
 # If GENERIC, make sure to turn off any instruction set extensions that
-# the host compiler might have on by default.  Given that EV4 and EV5
-# have the same instruction set, prefer EV5 because an EV5 schedule is
-# more likely to keep an EV4 processor busy than vice-versa.
-cpuflags-$(CONFIG_ALPHA_GENERIC)       := -mcpu=ev5
+# the host compiler might have on by default.
+cpuflags-$(CONFIG_ALPHA_GENERIC)       := -mcpu=ev56 -mtune=ev6
 
 cflags-y                               += $(cpuflags-y)
 
diff --git a/arch/alpha/include/asm/core_apecs.h b/arch/alpha/include/asm/core_apecs.h
deleted file mode 100644 (file)
index 69a2fc6..0000000
+++ /dev/null
@@ -1,534 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_APECS__H__
-#define __ALPHA_APECS__H__
-
-#include <linux/types.h>
-#include <asm/compiler.h>
-
-/*
- * APECS is the internal name for the 2107x chipset which provides
- * memory controller and PCI access for the 21064 chip based systems.
- *
- * This file is based on:
- *
- * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets
- * Data Sheet
- *
- * EC-N0648-72
- *
- *
- * david.rusling@reo.mts.dec.com Initial Version.
- *
- */
-
-/*
-   An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
-   that get passed through the PCI<->ISA bridge chip. So we've gotta use
-   both windows to max out the physical memory we can DMA to. Sigh...
-
-   If we try a window at 0 for 1GB as a work-around, we run into conflicts
-   with ISA/PCI bus memory which can't be relocated, like VGA aperture and
-   BIOS ROMs. So we must put the windows high enough to avoid these areas.
-
-   We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1,
-   and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1.
-   Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually
-   be used for that range (via virt_to_bus()).
-
-   Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb,
-   to keep virt_to_bus() from returning an address in the first window, for
-   a data area that goes beyond the 64Mb first DMA window.  Sigh...
-   The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but
-   we can't just use that here, because of header file looping... :-(
-
-   Window 1 will be used for all DMA from the ISA bus; yes, that does
-   limit what memory an ISA floppy or sound card or Ethernet can touch, but
-   it's also a known limitation on other platforms as well. We use the
-   same technique that is used on INTEL platforms with similar limitation:
-   set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init().
-   We trust that any ISA bus device drivers will *always* ask for DMAable
-   memory explicitly via kmalloc()/get_free_pages() flags arguments.
-
-   Note that most PCI bus devices' drivers do *not* explicitly ask for
-   DMAable memory; they count on being able to DMA to any memory they
-   get from kmalloc()/get_free_pages(). They will also use window 1 for
-   any physical memory accesses below 64Mb; the rest will be handled by
-   window 2, maxing out at 1Gb of memory. I trust this is enough... :-)
-
-   We hope that the area before the first window is large enough so that
-   there will be no overlap at the top end (64Mb). We *must* locate the
-   PCI cards' memory just below window 1, so that there's still the
-   possibility of being able to access it via SPARSE space. This is
-   important for cards such as the Matrox Millennium, whose Xserver
-   wants to access memory-mapped registers in byte and short lengths.
-
-   Note that the XL is treated differently from the AVANTI, even though
-   for most other things they are identical. It didn't seem reasonable to
-   make the AVANTI support pay for the limitations of the XL. It is true,
-   however, that an XL kernel will run on an AVANTI without problems.
-
-   %%% All of this should be obviated by the ability to route
-   everything through the iommu.
-*/
-
-/*
- * 21071-DA Control and Status registers.
- * These are used for PCI memory access.
- */
-#define APECS_IOC_DCSR                  (IDENT_ADDR + 0x1A0000000UL)
-#define APECS_IOC_PEAR                  (IDENT_ADDR + 0x1A0000020UL)
-#define APECS_IOC_SEAR                  (IDENT_ADDR + 0x1A0000040UL)
-#define APECS_IOC_DR1                   (IDENT_ADDR + 0x1A0000060UL)
-#define APECS_IOC_DR2                   (IDENT_ADDR + 0x1A0000080UL)
-#define APECS_IOC_DR3                   (IDENT_ADDR + 0x1A00000A0UL)
-
-#define APECS_IOC_TB1R                  (IDENT_ADDR + 0x1A00000C0UL)
-#define APECS_IOC_TB2R                  (IDENT_ADDR + 0x1A00000E0UL)
-
-#define APECS_IOC_PB1R                  (IDENT_ADDR + 0x1A0000100UL)
-#define APECS_IOC_PB2R                  (IDENT_ADDR + 0x1A0000120UL)
-
-#define APECS_IOC_PM1R                  (IDENT_ADDR + 0x1A0000140UL)
-#define APECS_IOC_PM2R                  (IDENT_ADDR + 0x1A0000160UL)
-
-#define APECS_IOC_HAXR0                 (IDENT_ADDR + 0x1A0000180UL)
-#define APECS_IOC_HAXR1                 (IDENT_ADDR + 0x1A00001A0UL)
-#define APECS_IOC_HAXR2                 (IDENT_ADDR + 0x1A00001C0UL)
-
-#define APECS_IOC_PMLT                  (IDENT_ADDR + 0x1A00001E0UL)
-
-#define APECS_IOC_TLBTAG0               (IDENT_ADDR + 0x1A0000200UL)
-#define APECS_IOC_TLBTAG1               (IDENT_ADDR + 0x1A0000220UL)
-#define APECS_IOC_TLBTAG2               (IDENT_ADDR + 0x1A0000240UL)
-#define APECS_IOC_TLBTAG3               (IDENT_ADDR + 0x1A0000260UL)
-#define APECS_IOC_TLBTAG4               (IDENT_ADDR + 0x1A0000280UL)
-#define APECS_IOC_TLBTAG5               (IDENT_ADDR + 0x1A00002A0UL)
-#define APECS_IOC_TLBTAG6               (IDENT_ADDR + 0x1A00002C0UL)
-#define APECS_IOC_TLBTAG7               (IDENT_ADDR + 0x1A00002E0UL)
-
-#define APECS_IOC_TLBDATA0              (IDENT_ADDR + 0x1A0000300UL)
-#define APECS_IOC_TLBDATA1              (IDENT_ADDR + 0x1A0000320UL)
-#define APECS_IOC_TLBDATA2              (IDENT_ADDR + 0x1A0000340UL)
-#define APECS_IOC_TLBDATA3              (IDENT_ADDR + 0x1A0000360UL)
-#define APECS_IOC_TLBDATA4              (IDENT_ADDR + 0x1A0000380UL)
-#define APECS_IOC_TLBDATA5              (IDENT_ADDR + 0x1A00003A0UL)
-#define APECS_IOC_TLBDATA6              (IDENT_ADDR + 0x1A00003C0UL)
-#define APECS_IOC_TLBDATA7              (IDENT_ADDR + 0x1A00003E0UL)
-
-#define APECS_IOC_TBIA                  (IDENT_ADDR + 0x1A0000400UL)
-
-
-/*
- * 21071-CA Control and Status registers.
- * These are used to program memory timing,
- *  configure memory and initialise the B-Cache.
- */
-#define APECS_MEM_GCR                  (IDENT_ADDR + 0x180000000UL)
-#define APECS_MEM_EDSR                 (IDENT_ADDR + 0x180000040UL)
-#define APECS_MEM_TAR                          (IDENT_ADDR + 0x180000060UL)
-#define APECS_MEM_ELAR                 (IDENT_ADDR + 0x180000080UL)
-#define APECS_MEM_EHAR                 (IDENT_ADDR + 0x1800000a0UL)
-#define APECS_MEM_SFT_RST              (IDENT_ADDR + 0x1800000c0UL)
-#define APECS_MEM_LDxLAR               (IDENT_ADDR + 0x1800000e0UL)
-#define APECS_MEM_LDxHAR               (IDENT_ADDR + 0x180000100UL)
-#define APECS_MEM_GTR                  (IDENT_ADDR + 0x180000200UL)
-#define APECS_MEM_RTR                  (IDENT_ADDR + 0x180000220UL)
-#define APECS_MEM_VFPR                 (IDENT_ADDR + 0x180000240UL)
-#define APECS_MEM_PDLDR                (IDENT_ADDR + 0x180000260UL)
-#define APECS_MEM_PDhDR                (IDENT_ADDR + 0x180000280UL)
-
-/* Bank x Base Address Register */
-#define APECS_MEM_B0BAR                (IDENT_ADDR + 0x180000800UL)
-#define APECS_MEM_B1BAR                (IDENT_ADDR + 0x180000820UL)
-#define APECS_MEM_B2BAR                (IDENT_ADDR + 0x180000840UL)
-#define APECS_MEM_B3BAR                (IDENT_ADDR + 0x180000860UL)
-#define APECS_MEM_B4BAR                (IDENT_ADDR + 0x180000880UL)
-#define APECS_MEM_B5BAR                (IDENT_ADDR + 0x1800008A0UL)
-#define APECS_MEM_B6BAR                (IDENT_ADDR + 0x1800008C0UL)
-#define APECS_MEM_B7BAR                (IDENT_ADDR + 0x1800008E0UL)
-#define APECS_MEM_B8BAR                (IDENT_ADDR + 0x180000900UL)
-
-/* Bank x Configuration Register */
-#define APECS_MEM_B0BCR                (IDENT_ADDR + 0x180000A00UL)
-#define APECS_MEM_B1BCR                (IDENT_ADDR + 0x180000A20UL)
-#define APECS_MEM_B2BCR                (IDENT_ADDR + 0x180000A40UL)
-#define APECS_MEM_B3BCR                (IDENT_ADDR + 0x180000A60UL)
-#define APECS_MEM_B4BCR                (IDENT_ADDR + 0x180000A80UL)
-#define APECS_MEM_B5BCR                (IDENT_ADDR + 0x180000AA0UL)
-#define APECS_MEM_B6BCR                (IDENT_ADDR + 0x180000AC0UL)
-#define APECS_MEM_B7BCR                (IDENT_ADDR + 0x180000AE0UL)
-#define APECS_MEM_B8BCR                (IDENT_ADDR + 0x180000B00UL)
-
-/* Bank x Timing Register A */
-#define APECS_MEM_B0TRA                (IDENT_ADDR + 0x180000C00UL)
-#define APECS_MEM_B1TRA                (IDENT_ADDR + 0x180000C20UL)
-#define APECS_MEM_B2TRA                (IDENT_ADDR + 0x180000C40UL)
-#define APECS_MEM_B3TRA                (IDENT_ADDR + 0x180000C60UL)
-#define APECS_MEM_B4TRA                (IDENT_ADDR + 0x180000C80UL)
-#define APECS_MEM_B5TRA                (IDENT_ADDR + 0x180000CA0UL)
-#define APECS_MEM_B6TRA                (IDENT_ADDR + 0x180000CC0UL)
-#define APECS_MEM_B7TRA                (IDENT_ADDR + 0x180000CE0UL)
-#define APECS_MEM_B8TRA                (IDENT_ADDR + 0x180000D00UL)
-
-/* Bank x Timing Register B */
-#define APECS_MEM_B0TRB                 (IDENT_ADDR + 0x180000E00UL)
-#define APECS_MEM_B1TRB                (IDENT_ADDR + 0x180000E20UL)
-#define APECS_MEM_B2TRB                (IDENT_ADDR + 0x180000E40UL)
-#define APECS_MEM_B3TRB                (IDENT_ADDR + 0x180000E60UL)
-#define APECS_MEM_B4TRB                (IDENT_ADDR + 0x180000E80UL)
-#define APECS_MEM_B5TRB                (IDENT_ADDR + 0x180000EA0UL)
-#define APECS_MEM_B6TRB                (IDENT_ADDR + 0x180000EC0UL)
-#define APECS_MEM_B7TRB                (IDENT_ADDR + 0x180000EE0UL)
-#define APECS_MEM_B8TRB                (IDENT_ADDR + 0x180000F00UL)
-
-
-/*
- * Memory spaces:
- */
-#define APECS_IACK_SC                  (IDENT_ADDR + 0x1b0000000UL)
-#define APECS_CONF                     (IDENT_ADDR + 0x1e0000000UL)
-#define APECS_IO                       (IDENT_ADDR + 0x1c0000000UL)
-#define APECS_SPARSE_MEM               (IDENT_ADDR + 0x200000000UL)
-#define APECS_DENSE_MEM                        (IDENT_ADDR + 0x300000000UL)
-
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define APECS_IOC_STAT0_CMD            0xf
-#define APECS_IOC_STAT0_ERR            (1<<4)
-#define APECS_IOC_STAT0_LOST           (1<<5)
-#define APECS_IOC_STAT0_THIT           (1<<6)
-#define APECS_IOC_STAT0_TREF           (1<<7)
-#define APECS_IOC_STAT0_CODE_SHIFT     8
-#define APECS_IOC_STAT0_CODE_MASK      0x7
-#define APECS_IOC_STAT0_P_NBR_SHIFT    13
-#define APECS_IOC_STAT0_P_NBR_MASK     0x7ffff
-
-#define APECS_HAE_ADDRESS              APECS_IOC_HAXR1
-
-
-/*
- * Data structure for handling APECS machine checks:
- */
-
-struct el_apecs_mikasa_sysdata_mcheck
-{
-       unsigned long coma_gcr;
-       unsigned long coma_edsr;
-       unsigned long coma_ter;
-       unsigned long coma_elar;
-       unsigned long coma_ehar;
-       unsigned long coma_ldlr;
-       unsigned long coma_ldhr;
-       unsigned long coma_base0;
-       unsigned long coma_base1;
-       unsigned long coma_base2;
-       unsigned long coma_base3;
-       unsigned long coma_cnfg0;
-       unsigned long coma_cnfg1;
-       unsigned long coma_cnfg2;
-       unsigned long coma_cnfg3;
-       unsigned long epic_dcsr;
-       unsigned long epic_pear;
-       unsigned long epic_sear;
-       unsigned long epic_tbr1;
-       unsigned long epic_tbr2;
-       unsigned long epic_pbr1;
-       unsigned long epic_pbr2;
-       unsigned long epic_pmr1;
-       unsigned long epic_pmr2;
-       unsigned long epic_harx1;
-       unsigned long epic_harx2;
-       unsigned long epic_pmlt;
-       unsigned long epic_tag0;
-       unsigned long epic_tag1;
-       unsigned long epic_tag2;
-       unsigned long epic_tag3;
-       unsigned long epic_tag4;
-       unsigned long epic_tag5;
-       unsigned long epic_tag6;
-       unsigned long epic_tag7;
-       unsigned long epic_data0;
-       unsigned long epic_data1;
-       unsigned long epic_data2;
-       unsigned long epic_data3;
-       unsigned long epic_data4;
-       unsigned long epic_data5;
-       unsigned long epic_data6;
-       unsigned long epic_data7;
-
-       unsigned long pceb_vid;
-       unsigned long pceb_did;
-       unsigned long pceb_revision;
-       unsigned long pceb_command;
-       unsigned long pceb_status;
-       unsigned long pceb_latency;
-       unsigned long pceb_control;
-       unsigned long pceb_arbcon;
-       unsigned long pceb_arbpri;
-
-       unsigned long esc_id;
-       unsigned long esc_revision;
-       unsigned long esc_int0;
-       unsigned long esc_int1;
-       unsigned long esc_elcr0;
-       unsigned long esc_elcr1;
-       unsigned long esc_last_eisa;
-       unsigned long esc_nmi_stat;
-
-       unsigned long pci_ir;
-       unsigned long pci_imr;
-       unsigned long svr_mgr;
-};
-
-/* This for the normal APECS machines.  */
-struct el_apecs_sysdata_mcheck
-{
-       unsigned long coma_gcr;
-       unsigned long coma_edsr;
-       unsigned long coma_ter;
-       unsigned long coma_elar;
-       unsigned long coma_ehar;
-       unsigned long coma_ldlr;
-       unsigned long coma_ldhr;
-       unsigned long coma_base0;
-       unsigned long coma_base1;
-       unsigned long coma_base2;
-       unsigned long coma_cnfg0;
-       unsigned long coma_cnfg1;
-       unsigned long coma_cnfg2;
-       unsigned long epic_dcsr;
-       unsigned long epic_pear;
-       unsigned long epic_sear;
-       unsigned long epic_tbr1;
-       unsigned long epic_tbr2;
-       unsigned long epic_pbr1;
-       unsigned long epic_pbr2;
-       unsigned long epic_pmr1;
-       unsigned long epic_pmr2;
-       unsigned long epic_harx1;
-       unsigned long epic_harx2;
-       unsigned long epic_pmlt;
-       unsigned long epic_tag0;
-       unsigned long epic_tag1;
-       unsigned long epic_tag2;
-       unsigned long epic_tag3;
-       unsigned long epic_tag4;
-       unsigned long epic_tag5;
-       unsigned long epic_tag6;
-       unsigned long epic_tag7;
-       unsigned long epic_data0;
-       unsigned long epic_data1;
-       unsigned long epic_data2;
-       unsigned long epic_data3;
-       unsigned long epic_data4;
-       unsigned long epic_data5;
-       unsigned long epic_data6;
-       unsigned long epic_data7;
-};
-
-struct el_apecs_procdata
-{
-       unsigned long paltemp[32];  /* PAL TEMP REGS. */
-       /* EV4-specific fields */
-       unsigned long exc_addr;     /* Address of excepting instruction. */
-       unsigned long exc_sum;      /* Summary of arithmetic traps. */
-       unsigned long exc_mask;     /* Exception mask (from exc_sum). */
-       unsigned long iccsr;        /* IBox hardware enables. */
-       unsigned long pal_base;     /* Base address for PALcode. */
-       unsigned long hier;         /* Hardware Interrupt Enable. */
-       unsigned long hirr;         /* Hardware Interrupt Request. */
-       unsigned long csr;          /* D-stream fault info. */
-       unsigned long dc_stat;      /* D-cache status (ECC/Parity Err). */
-       unsigned long dc_addr;      /* EV3 Phys Addr for ECC/DPERR. */
-       unsigned long abox_ctl;     /* ABox Control Register. */
-       unsigned long biu_stat;     /* BIU Status. */
-       unsigned long biu_addr;     /* BUI Address. */
-       unsigned long biu_ctl;      /* BIU Control. */
-       unsigned long fill_syndrome;/* For correcting ECC errors. */
-       unsigned long fill_addr;    /* Cache block which was being read */
-       unsigned long va;           /* Effective VA of fault or miss. */
-       unsigned long bc_tag;       /* Backup Cache Tag Probe Results.*/
-};
-
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the APECS machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here.  In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vip    volatile int __force *
-#define vuip   volatile unsigned int __force *
-#define vulp   volatile unsigned long __force *
-
-#define APECS_SET_HAE                                          \
-       do {                                                    \
-               if (addr >= (1UL << 24)) {                      \
-                       unsigned long msb = addr & 0xf8000000;  \
-                       addr -= msb;                            \
-                       set_hae(msb);                           \
-               }                                               \
-       } while (0)
-
-__EXTERN_INLINE u8 apecs_ioread8(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long result, base_and_type;
-
-       if (addr >= APECS_DENSE_MEM) {
-               addr -= APECS_DENSE_MEM;
-               APECS_SET_HAE;
-               base_and_type = APECS_SPARSE_MEM + 0x00;
-       } else {
-               addr -= APECS_IO;
-               base_and_type = APECS_IO + 0x00;
-       }
-
-       result = *(vip) ((addr << 5) + base_and_type);
-       return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long w, base_and_type;
-
-       if (addr >= APECS_DENSE_MEM) {
-               addr -= APECS_DENSE_MEM;
-               APECS_SET_HAE;
-               base_and_type = APECS_SPARSE_MEM + 0x00;
-       } else {
-               addr -= APECS_IO;
-               base_and_type = APECS_IO + 0x00;
-       }
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u16 apecs_ioread16(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long result, base_and_type;
-
-       if (addr >= APECS_DENSE_MEM) {
-               addr -= APECS_DENSE_MEM;
-               APECS_SET_HAE;
-               base_and_type = APECS_SPARSE_MEM + 0x08;
-       } else {
-               addr -= APECS_IO;
-               base_and_type = APECS_IO + 0x08;
-       }
-
-       result = *(vip) ((addr << 5) + base_and_type);
-       return __kernel_extwl(result, addr & 3);
-}
-
-__EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long w, base_and_type;
-
-       if (addr >= APECS_DENSE_MEM) {
-               addr -= APECS_DENSE_MEM;
-               APECS_SET_HAE;
-               base_and_type = APECS_SPARSE_MEM + 0x08;
-       } else {
-               addr -= APECS_IO;
-               base_and_type = APECS_IO + 0x08;
-       }
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u32 apecs_ioread32(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < APECS_DENSE_MEM)
-               addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
-       return *(vuip)addr;
-}
-
-__EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < APECS_DENSE_MEM)
-               addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
-       *(vuip)addr = b;
-}
-
-__EXTERN_INLINE u64 apecs_ioread64(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < APECS_DENSE_MEM)
-               addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
-       return *(vulp)addr;
-}
-
-__EXTERN_INLINE void apecs_iowrite64(u64 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < APECS_DENSE_MEM)
-               addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18;
-       *(vulp)addr = b;
-}
-
-__EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr)
-{
-       return (void __iomem *)(addr + APECS_IO);
-}
-
-__EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr,
-                                           unsigned long size)
-{
-       return (void __iomem *)(addr + APECS_DENSE_MEM);
-}
-
-__EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr)
-{
-       return addr >= IDENT_ADDR + 0x180000000UL;
-}
-
-__EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr)
-{
-       return (unsigned long)addr >= APECS_DENSE_MEM;
-}
-
-#undef APECS_SET_HAE
-
-#undef vip
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX            apecs
-#define apecs_trivial_io_bw    0
-#define apecs_trivial_io_lq    0
-#define apecs_trivial_rw_bw    2
-#define apecs_trivial_rw_lq    1
-#define apecs_trivial_iounmap  1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_APECS__H__ */
diff --git a/arch/alpha/include/asm/core_lca.h b/arch/alpha/include/asm/core_lca.h
deleted file mode 100644 (file)
index d8c3e72..0000000
+++ /dev/null
@@ -1,378 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_LCA__H__
-#define __ALPHA_LCA__H__
-
-#include <asm/compiler.h>
-#include <asm/mce.h>
-
-/*
- * Low Cost Alpha (LCA) definitions (these apply to 21066 and 21068,
- * for example).
- *
- * This file is based on:
- *
- *     DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors
- *     Hardware Reference Manual; Digital Equipment Corp.; May 1994;
- *     Maynard, MA; Order Number: EC-N2681-71.
- */
-
-/*
- * NOTE: The LCA uses a Host Address Extension (HAE) register to access
- *      PCI addresses that are beyond the first 27 bits of address
- *      space.  Updating the HAE requires an external cycle (and
- *      a memory barrier), which tends to be slow.  Instead of updating
- *      it on each sparse memory access, we keep the current HAE value
- *      cached in variable cache_hae.  Only if the cached HAE differs
- *      from the desired HAE value do we actually updated HAE register.
- *      The HAE register is preserved by the interrupt handler entry/exit
- *      code, so this scheme works even in the presence of interrupts.
- *
- * Dense memory space doesn't require the HAE, but is restricted to
- * aligned 32 and 64 bit accesses.  Special Cycle and Interrupt
- * Acknowledge cycles may also require the use of the HAE.  The LCA
- * limits I/O address space to the bottom 24 bits of address space,
- * but this easily covers the 16 bit ISA I/O address space.
- */
-
-/*
- * NOTE 2! The memory operations do not set any memory barriers, as
- * it's not needed for cases like a frame buffer that is essentially
- * memory-like.  You need to do them by hand if the operations depend
- * on ordering.
- *
- * Similarly, the port I/O operations do a "mb" only after a write
- * operation: if an mb is needed before (as in the case of doing
- * memory mapped I/O first, and then a port I/O operation to the same
- * device), it needs to be done by hand.
- *
- * After the above has bitten me 100 times, I'll give up and just do
- * the mb all the time, but right now I'm hoping this will work out.
- * Avoiding mb's may potentially be a noticeable speed improvement,
- * but I can't honestly say I've tested it.
- *
- * Handling interrupts that need to do mb's to synchronize to
- * non-interrupts is another fun race area.  Don't do it (because if
- * you do, I'll have to do *everything* with interrupts disabled,
- * ugh).
- */
-
-/*
- * Memory Controller registers:
- */
-#define LCA_MEM_BCR0           (IDENT_ADDR + 0x120000000UL)
-#define LCA_MEM_BCR1           (IDENT_ADDR + 0x120000008UL)
-#define LCA_MEM_BCR2           (IDENT_ADDR + 0x120000010UL)
-#define LCA_MEM_BCR3           (IDENT_ADDR + 0x120000018UL)
-#define LCA_MEM_BMR0           (IDENT_ADDR + 0x120000020UL)
-#define LCA_MEM_BMR1           (IDENT_ADDR + 0x120000028UL)
-#define LCA_MEM_BMR2           (IDENT_ADDR + 0x120000030UL)
-#define LCA_MEM_BMR3           (IDENT_ADDR + 0x120000038UL)
-#define LCA_MEM_BTR0           (IDENT_ADDR + 0x120000040UL)
-#define LCA_MEM_BTR1           (IDENT_ADDR + 0x120000048UL)
-#define LCA_MEM_BTR2           (IDENT_ADDR + 0x120000050UL)
-#define LCA_MEM_BTR3           (IDENT_ADDR + 0x120000058UL)
-#define LCA_MEM_GTR            (IDENT_ADDR + 0x120000060UL)
-#define LCA_MEM_ESR            (IDENT_ADDR + 0x120000068UL)
-#define LCA_MEM_EAR            (IDENT_ADDR + 0x120000070UL)
-#define LCA_MEM_CAR            (IDENT_ADDR + 0x120000078UL)
-#define LCA_MEM_VGR            (IDENT_ADDR + 0x120000080UL)
-#define LCA_MEM_PLM            (IDENT_ADDR + 0x120000088UL)
-#define LCA_MEM_FOR            (IDENT_ADDR + 0x120000090UL)
-
-/*
- * I/O Controller registers:
- */
-#define LCA_IOC_HAE            (IDENT_ADDR + 0x180000000UL)
-#define LCA_IOC_CONF           (IDENT_ADDR + 0x180000020UL)
-#define LCA_IOC_STAT0          (IDENT_ADDR + 0x180000040UL)
-#define LCA_IOC_STAT1          (IDENT_ADDR + 0x180000060UL)
-#define LCA_IOC_TBIA           (IDENT_ADDR + 0x180000080UL)
-#define LCA_IOC_TB_ENA         (IDENT_ADDR + 0x1800000a0UL)
-#define LCA_IOC_SFT_RST                (IDENT_ADDR + 0x1800000c0UL)
-#define LCA_IOC_PAR_DIS                (IDENT_ADDR + 0x1800000e0UL)
-#define LCA_IOC_W_BASE0                (IDENT_ADDR + 0x180000100UL)
-#define LCA_IOC_W_BASE1                (IDENT_ADDR + 0x180000120UL)
-#define LCA_IOC_W_MASK0                (IDENT_ADDR + 0x180000140UL)
-#define LCA_IOC_W_MASK1                (IDENT_ADDR + 0x180000160UL)
-#define LCA_IOC_T_BASE0                (IDENT_ADDR + 0x180000180UL)
-#define LCA_IOC_T_BASE1                (IDENT_ADDR + 0x1800001a0UL)
-#define LCA_IOC_TB_TAG0                (IDENT_ADDR + 0x188000000UL)
-#define LCA_IOC_TB_TAG1                (IDENT_ADDR + 0x188000020UL)
-#define LCA_IOC_TB_TAG2                (IDENT_ADDR + 0x188000040UL)
-#define LCA_IOC_TB_TAG3                (IDENT_ADDR + 0x188000060UL)
-#define LCA_IOC_TB_TAG4                (IDENT_ADDR + 0x188000070UL)
-#define LCA_IOC_TB_TAG5                (IDENT_ADDR + 0x1880000a0UL)
-#define LCA_IOC_TB_TAG6                (IDENT_ADDR + 0x1880000c0UL)
-#define LCA_IOC_TB_TAG7                (IDENT_ADDR + 0x1880000e0UL)
-
-/*
- * Memory spaces:
- */
-#define LCA_IACK_SC            (IDENT_ADDR + 0x1a0000000UL)
-#define LCA_CONF               (IDENT_ADDR + 0x1e0000000UL)
-#define LCA_IO                 (IDENT_ADDR + 0x1c0000000UL)
-#define LCA_SPARSE_MEM         (IDENT_ADDR + 0x200000000UL)
-#define LCA_DENSE_MEM          (IDENT_ADDR + 0x300000000UL)
-
-/*
- * Bit definitions for I/O Controller status register 0:
- */
-#define LCA_IOC_STAT0_CMD              0xf
-#define LCA_IOC_STAT0_ERR              (1<<4)
-#define LCA_IOC_STAT0_LOST             (1<<5)
-#define LCA_IOC_STAT0_THIT             (1<<6)
-#define LCA_IOC_STAT0_TREF             (1<<7)
-#define LCA_IOC_STAT0_CODE_SHIFT       8
-#define LCA_IOC_STAT0_CODE_MASK                0x7
-#define LCA_IOC_STAT0_P_NBR_SHIFT      13
-#define LCA_IOC_STAT0_P_NBR_MASK       0x7ffff
-
-#define LCA_HAE_ADDRESS                LCA_IOC_HAE
-
-/* LCA PMR Power Management register defines */
-#define LCA_PMR_ADDR   (IDENT_ADDR + 0x120000098UL)
-#define LCA_PMR_PDIV    0x7                     /* Primary clock divisor */
-#define LCA_PMR_ODIV    0x38                    /* Override clock divisor */
-#define LCA_PMR_INTO    0x40                    /* Interrupt override */
-#define LCA_PMR_DMAO    0x80                    /* DMA override */
-#define LCA_PMR_OCCEB   0xffff0000L             /* Override cycle counter - even bits */
-#define LCA_PMR_OCCOB   0xffff000000000000L     /* Override cycle counter - even bits */
-#define LCA_PMR_PRIMARY_MASK    0xfffffffffffffff8L
-
-/* LCA PMR Macros */
-
-#define LCA_READ_PMR        (*(volatile unsigned long *)LCA_PMR_ADDR)
-#define LCA_WRITE_PMR(d)    (*((volatile unsigned long *)LCA_PMR_ADDR) = (d))
-
-#define LCA_GET_PRIMARY(r)  ((r) & LCA_PMR_PDIV)
-#define LCA_GET_OVERRIDE(r) (((r) >> 3) & LCA_PMR_PDIV)
-#define LCA_SET_PRIMARY_CLOCK(r, c) ((r) = (((r) & LCA_PMR_PRIMARY_MASK)|(c)))
-
-/* LCA PMR Divisor values */
-#define LCA_PMR_DIV_1   0x0
-#define LCA_PMR_DIV_1_5 0x1
-#define LCA_PMR_DIV_2   0x2
-#define LCA_PMR_DIV_4   0x3
-#define LCA_PMR_DIV_8   0x4
-#define LCA_PMR_DIV_16  0x5
-#define LCA_PMR_DIV_MIN DIV_1
-#define LCA_PMR_DIV_MAX DIV_16
-
-
-/*
- * Data structure for handling LCA machine checks.  Correctable errors
- * result in a short logout frame, uncorrectable ones in a long one.
- */
-struct el_lca_mcheck_short {
-       struct el_common        h;              /* common logout header */
-       unsigned long           esr;            /* error-status register */
-       unsigned long           ear;            /* error-address register */
-       unsigned long           dc_stat;        /* dcache status register */
-       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
-       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
-};
-
-struct el_lca_mcheck_long {
-       struct el_common        h;              /* common logout header */
-       unsigned long           pt[31];         /* PAL temps */
-       unsigned long           exc_addr;       /* exception address */
-       unsigned long           pad1[3];
-       unsigned long           pal_base;       /* PALcode base address */
-       unsigned long           hier;           /* hw interrupt enable */
-       unsigned long           hirr;           /* hw interrupt request */
-       unsigned long           mm_csr;         /* MMU control & status */
-       unsigned long           dc_stat;        /* data cache status */
-       unsigned long           dc_addr;        /* data cache addr register */
-       unsigned long           abox_ctl;       /* address box control register */
-       unsigned long           esr;            /* error status register */
-       unsigned long           ear;            /* error address register */
-       unsigned long           car;            /* cache control register */
-       unsigned long           ioc_stat0;      /* I/O controller status register 0 */
-       unsigned long           ioc_stat1;      /* I/O controller status register 1 */
-       unsigned long           va;             /* virtual address register */
-};
-
-union el_lca {
-       struct el_common *              c;
-       struct el_lca_mcheck_long *     l;
-       struct el_lca_mcheck_short *    s;
-};
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * I/O functions:
- *
- * Unlike Jensen, the Noname machines have no concept of local
- * I/O---everything goes over the PCI bus.
- *
- * There is plenty room for optimization here.  In particular,
- * the Alpha's insb/insw/extb/extw should be useful in moving
- * data to/from the right byte-lanes.
- */
-
-#define vip    volatile int __force *
-#define vuip   volatile unsigned int __force *
-#define vulp   volatile unsigned long __force *
-
-#define LCA_SET_HAE                                            \
-       do {                                                    \
-               if (addr >= (1UL << 24)) {                      \
-                       unsigned long msb = addr & 0xf8000000;  \
-                       addr -= msb;                            \
-                       set_hae(msb);                           \
-               }                                               \
-       } while (0)
-
-
-__EXTERN_INLINE u8 lca_ioread8(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long result, base_and_type;
-
-       if (addr >= LCA_DENSE_MEM) {
-               addr -= LCA_DENSE_MEM;
-               LCA_SET_HAE;
-               base_and_type = LCA_SPARSE_MEM + 0x00;
-       } else {
-               addr -= LCA_IO;
-               base_and_type = LCA_IO + 0x00;
-       }
-
-       result = *(vip) ((addr << 5) + base_and_type);
-       return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long w, base_and_type;
-
-       if (addr >= LCA_DENSE_MEM) {
-               addr -= LCA_DENSE_MEM;
-               LCA_SET_HAE;
-               base_and_type = LCA_SPARSE_MEM + 0x00;
-       } else {
-               addr -= LCA_IO;
-               base_and_type = LCA_IO + 0x00;
-       }
-
-       w = __kernel_insbl(b, addr & 3);
-       *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u16 lca_ioread16(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long result, base_and_type;
-
-       if (addr >= LCA_DENSE_MEM) {
-               addr -= LCA_DENSE_MEM;
-               LCA_SET_HAE;
-               base_and_type = LCA_SPARSE_MEM + 0x08;
-       } else {
-               addr -= LCA_IO;
-               base_and_type = LCA_IO + 0x08;
-       }
-
-       result = *(vip) ((addr << 5) + base_and_type);
-       return __kernel_extwl(result, addr & 3);
-}
-
-__EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long w, base_and_type;
-
-       if (addr >= LCA_DENSE_MEM) {
-               addr -= LCA_DENSE_MEM;
-               LCA_SET_HAE;
-               base_and_type = LCA_SPARSE_MEM + 0x08;
-       } else {
-               addr -= LCA_IO;
-               base_and_type = LCA_IO + 0x08;
-       }
-
-       w = __kernel_inswl(b, addr & 3);
-       *(vuip) ((addr << 5) + base_and_type) = w;
-}
-
-__EXTERN_INLINE u32 lca_ioread32(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < LCA_DENSE_MEM)
-               addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
-       return *(vuip)addr;
-}
-
-__EXTERN_INLINE void lca_iowrite32(u32 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < LCA_DENSE_MEM)
-               addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
-       *(vuip)addr = b;
-}
-
-__EXTERN_INLINE u64 lca_ioread64(const void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < LCA_DENSE_MEM)
-               addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
-       return *(vulp)addr;
-}
-
-__EXTERN_INLINE void lca_iowrite64(u64 b, void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       if (addr < LCA_DENSE_MEM)
-               addr = ((addr - LCA_IO) << 5) + LCA_IO + 0x18;
-       *(vulp)addr = b;
-}
-
-__EXTERN_INLINE void __iomem *lca_ioportmap(unsigned long addr)
-{
-       return (void __iomem *)(addr + LCA_IO);
-}
-
-__EXTERN_INLINE void __iomem *lca_ioremap(unsigned long addr,
-                                         unsigned long size)
-{
-       return (void __iomem *)(addr + LCA_DENSE_MEM);
-}
-
-__EXTERN_INLINE int lca_is_ioaddr(unsigned long addr)
-{
-       return addr >= IDENT_ADDR + 0x120000000UL;
-}
-
-__EXTERN_INLINE int lca_is_mmio(const volatile void __iomem *addr)
-{
-       return (unsigned long)addr >= LCA_DENSE_MEM;
-}
-
-#undef vip
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX            lca
-#define lca_trivial_rw_bw      2
-#define lca_trivial_rw_lq      1
-#define lca_trivial_io_bw      0
-#define lca_trivial_io_lq      0
-#define lca_trivial_iounmap    1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_LCA__H__ */
index ab956b1625b53a444e6225d32d937cc62c8e473d..ca9b091d9c5fd7eb8d830101de34bf8dac8cc1fd 100644 (file)
 #define T2_MEM_R1_MASK 0x07ffffff  /* Mem sparse region 1 mask is 27 bits */
 
 /* GAMMA-SABLE is a SABLE with EV5-based CPUs */
-/* All LYNX machines, EV4 or EV5, use the GAMMA bias also */
 #define _GAMMA_BIAS            0x8000000000UL
-
-#if defined(CONFIG_ALPHA_GENERIC)
-#define GAMMA_BIAS             alpha_mv.sys.t2.gamma_bias
-#elif defined(CONFIG_ALPHA_GAMMA)
 #define GAMMA_BIAS             _GAMMA_BIAS
-#else
-#define GAMMA_BIAS             0
-#endif
 
 /*
  * Memory spaces:
index 6ce7e2041685b3232bae8962215f13f72418785d..ad5a59b035cbce9dea453449ecebc0466987693f 100644 (file)
@@ -6,11 +6,7 @@ extern const struct dma_map_ops alpha_pci_ops;
 
 static inline const struct dma_map_ops *get_arch_dma_ops(void)
 {
-#ifdef CONFIG_ALPHA_JENSEN
-       return NULL;
-#else
        return &alpha_pci_ops;
-#endif
 }
 
 #endif /* _ALPHA_DMA_MAPPING_H */
index a04d76b96089e5b7a975941dcbc3067f88959ec7..3a88812b71652232014c988f45ec240abf0e9ac7 100644 (file)
   just a wiring limit.
 */
 
-/* The maximum address for ISA DMA transfer on Alpha XL, due to an
-   hardware SIO limitation, is 64MB.
-*/
-#define ALPHA_XL_MAX_ISA_DMA_ADDRESS           0x04000000UL
-
 /* The maximum address for ISA DMA transfer on RUFFIAN,
    due to an hardware SIO limitation, is 16MB.
 */
 #ifdef CONFIG_ALPHA_GENERIC
 # define MAX_ISA_DMA_ADDRESS           (alpha_mv.max_isa_dma_address)
 #else
-# if defined(CONFIG_ALPHA_XL)
-#  define MAX_ISA_DMA_ADDRESS          ALPHA_XL_MAX_ISA_DMA_ADDRESS
-# elif defined(CONFIG_ALPHA_RUFFIAN)
+# if defined(CONFIG_ALPHA_RUFFIAN)
 #  define MAX_ISA_DMA_ADDRESS          ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS
 # elif defined(CONFIG_ALPHA_SABLE)
 #  define MAX_ISA_DMA_ADDRESS          ALPHA_SABLE_MAX_ISA_DMA_ADDRESS
index e6da23f1da830a672022811392a2e3a77bd57632..4d7c46f50382e37c5cfbba2fd9e1c3670a331631 100644 (file)
@@ -133,9 +133,7 @@ extern int dump_elf_task(elf_greg_t *dest, struct task_struct *task);
 #define ELF_PLATFORM                           \
 ({                                             \
        enum implver_enum i_ = implver();       \
-       ( i_ == IMPLVER_EV4 ? "ev4"             \
-       : i_ == IMPLVER_EV5                     \
-         ? (amask(AMASK_BWX) ? "ev5" : "ev56") \
+       ( i_ == IMPLVER_EV5 ? "ev56"                    \
        : amask (AMASK_CIX) ? "ev6" : "ev67");  \
 })
 
index 4f47a5003fe88ab0c4c1869fe713b15201335513..2bb8cbeedf9160778a7bff1a444f8bc925612749 100644 (file)
@@ -203,16 +203,10 @@ static inline int generic_is_mmio(const volatile void __iomem *a)
 
 #else
 
-#if defined(CONFIG_ALPHA_APECS)
-# include <asm/core_apecs.h>
-#elif defined(CONFIG_ALPHA_CIA)
+#if defined(CONFIG_ALPHA_CIA)
 # include <asm/core_cia.h>
 #elif defined(CONFIG_ALPHA_IRONGATE)
 # include <asm/core_irongate.h>
-#elif defined(CONFIG_ALPHA_JENSEN)
-# include <asm/jensen.h>
-#elif defined(CONFIG_ALPHA_LCA)
-# include <asm/core_lca.h>
 #elif defined(CONFIG_ALPHA_MARVEL)
 # include <asm/core_marvel.h>
 #elif defined(CONFIG_ALPHA_MCPCIA)
@@ -631,23 +625,7 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
 #define outsw outsw
 #define outsl outsl
 
-/*
- * The Alpha Jensen hardware for some rather strange reason puts
- * the RTC clock at 0x170 instead of 0x70. Probably due to some
- * misguided idea about using 0x70 for NMI stuff.
- *
- * These defines will override the defaults when doing RTC queries
- */
-
-#ifdef CONFIG_ALPHA_GENERIC
-# define RTC_PORT(x)   ((x) + alpha_mv.rtc_port)
-#else
-# ifdef CONFIG_ALPHA_JENSEN
-#  define RTC_PORT(x)  (0x170+(x))
-# else
-#  define RTC_PORT(x)  (0x70 + (x))
-# endif
-#endif
+#define RTC_PORT(x)    (0x70 + (x))
 #define RTC_ALWAYS_BCD 0
 
 /*
index 432402c8e47f5b8e1126fae0e2971d74d9d95f76..d83b26b6660f14f8ead0afedcffe93183f65343e 100644 (file)
 #  define NR_IRQS      (32768 + 16)    /* marvel - 32 pids */
 # endif
 
-#elif defined(CONFIG_ALPHA_CABRIOLET) || \
-      defined(CONFIG_ALPHA_EB66P)     || \
-      defined(CONFIG_ALPHA_EB164)     || \
-      defined(CONFIG_ALPHA_PC164)     || \
+#elif defined(CONFIG_ALPHA_PC164)     || \
       defined(CONFIG_ALPHA_LX164)
 # define NR_IRQS       35
 
-#elif defined(CONFIG_ALPHA_EB66)      || \
-      defined(CONFIG_ALPHA_EB64P)     || \
-      defined(CONFIG_ALPHA_MIKASA)
+#elif defined(CONFIG_ALPHA_MIKASA)
 # define NR_IRQS       32
 
 #elif defined(CONFIG_ALPHA_ALCOR)     || \
@@ -55,7 +50,6 @@
 # define NR_IRQS       40
 
 #elif defined(CONFIG_ALPHA_DP264) || \
-      defined(CONFIG_ALPHA_LYNX)  || \
       defined(CONFIG_ALPHA_SHARK)
 # define NR_IRQS       64
 
diff --git a/arch/alpha/include/asm/jensen.h b/arch/alpha/include/asm/jensen.h
deleted file mode 100644 (file)
index 66eb049..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ALPHA_JENSEN_H
-#define __ALPHA_JENSEN_H
-
-#include <asm/compiler.h>
-
-/*
- * Defines for the AlphaPC EISA IO and memory address space.
- */
-
-/*
- * NOTE! The memory operations do not set any memory barriers, as it's
- * not needed for cases like a frame buffer that is essentially memory-like.
- * You need to do them by hand if the operations depend on ordering.
- *
- * Similarly, the port IO operations do a "mb" only after a write operation:
- * if an mb is needed before (as in the case of doing memory mapped IO
- * first, and then a port IO operation to the same device), it needs to be
- * done by hand.
- *
- * After the above has bitten me 100 times, I'll give up and just do the
- * mb all the time, but right now I'm hoping this will work out.  Avoiding
- * mb's may potentially be a noticeable speed improvement, but I can't
- * honestly say I've tested it.
- *
- * Handling interrupts that need to do mb's to synchronize to non-interrupts
- * is another fun race area.  Don't do it (because if you do, I'll have to
- * do *everything* with interrupts disabled, ugh).
- */
-
-/*
- * EISA Interrupt Acknowledge address
- */
-#define EISA_INTA              (IDENT_ADDR + 0x100000000UL)
-
-/*
- * FEPROM addresses
- */
-#define EISA_FEPROM0           (IDENT_ADDR + 0x180000000UL)
-#define EISA_FEPROM1           (IDENT_ADDR + 0x1A0000000UL)
-
-/*
- * VL82C106 base address
- */
-#define EISA_VL82C106          (IDENT_ADDR + 0x1C0000000UL)
-
-/*
- * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
- */
-#define EISA_HAE               (IDENT_ADDR + 0x1D0000000UL)
-
-/*
- * "SYSCTL" register address
- */
-#define EISA_SYSCTL            (IDENT_ADDR + 0x1E0000000UL)
-
-/*
- * "spare" register address
- */
-#define EISA_SPARE             (IDENT_ADDR + 0x1F0000000UL)
-
-/*
- * EISA memory address offset
- */
-#define EISA_MEM               (IDENT_ADDR + 0x200000000UL)
-
-/*
- * EISA IO address offset
- */
-#define EISA_IO                        (IDENT_ADDR + 0x300000000UL)
-
-
-#ifdef __KERNEL__
-
-#ifndef __EXTERN_INLINE
-#define __EXTERN_INLINE extern inline
-#define __IO_EXTERN_INLINE
-#endif
-
-/*
- * Handle the "host address register". This needs to be set
- * to the high 7 bits of the EISA address.  This is also needed
- * for EISA IO addresses, which are only 16 bits wide (the
- * hae needs to be set to 0).
- *
- * HAE isn't needed for the local IO operations, though.
- */
-
-#define JENSEN_HAE_ADDRESS     EISA_HAE
-#define JENSEN_HAE_MASK                0x1ffffff
-
-__EXTERN_INLINE void jensen_set_hae(unsigned long addr)
-{
-       /* hae on the Jensen is bits 31:25 shifted right */
-       addr >>= 25;
-       if (addr != alpha_mv.hae_cache)
-               set_hae(addr);
-}
-
-#define vuip   volatile unsigned int *
-#define vulp   volatile unsigned long *
-
-/*
- * IO functions
- *
- * The "local" functions are those that don't go out to the EISA bus,
- * but instead act on the VL82C106 chip directly.. This is mainly the
- * keyboard, RTC,  printer and first two serial lines..
- *
- * The local stuff makes for some complications, but it seems to be
- * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
- * convinced that I need one of the newer machines.
- */
-
-__EXTERN_INLINE unsigned int jensen_local_inb(unsigned long addr)
-{
-       return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
-}
-
-__EXTERN_INLINE void jensen_local_outb(u8 b, unsigned long addr)
-{
-       *(vuip)((addr << 9) + EISA_VL82C106) = b;
-       mb();
-}
-
-__EXTERN_INLINE unsigned int jensen_bus_inb(unsigned long addr)
-{
-       long result;
-
-       jensen_set_hae(0);
-       result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
-       return __kernel_extbl(result, addr & 3);
-}
-
-__EXTERN_INLINE void jensen_bus_outb(u8 b, unsigned long addr)
-{
-       jensen_set_hae(0);
-       *(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
-       mb();
-}
-
-/*
- * It seems gcc is not very good at optimizing away logical
- * operations that result in operations across inline functions.
- * Which is why this is a macro.
- */
-
-#define jensen_is_local(addr) ( \
-/* keyboard */ (addr == 0x60 || addr == 0x64) || \
-/* RTC */      (addr == 0x170 || addr == 0x171) || \
-/* mb COM2 */  (addr >= 0x2f8 && addr <= 0x2ff) || \
-/* mb LPT1 */  (addr >= 0x3bc && addr <= 0x3be) || \
-/* mb COM2 */  (addr >= 0x3f8 && addr <= 0x3ff))
-
-__EXTERN_INLINE u8 jensen_inb(unsigned long addr)
-{
-       if (jensen_is_local(addr))
-               return jensen_local_inb(addr);
-       else
-               return jensen_bus_inb(addr);
-}
-
-__EXTERN_INLINE void jensen_outb(u8 b, unsigned long addr)
-{
-       if (jensen_is_local(addr))
-               jensen_local_outb(b, addr);
-       else
-               jensen_bus_outb(b, addr);
-}
-
-__EXTERN_INLINE u16 jensen_inw(unsigned long addr)
-{
-       long result;
-
-       jensen_set_hae(0);
-       result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-__EXTERN_INLINE u32 jensen_inl(unsigned long addr)
-{
-       jensen_set_hae(0);
-       return *(vuip) ((addr << 7) + EISA_IO + 0x60);
-}
-
-__EXTERN_INLINE u64 jensen_inq(unsigned long addr)
-{
-       jensen_set_hae(0);
-       return *(vulp) ((addr << 7) + EISA_IO + 0x60);
-}
-
-__EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
-{
-       jensen_set_hae(0);
-       *(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
-       mb();
-}
-
-__EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
-{
-       jensen_set_hae(0);
-       *(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
-       mb();
-}
-
-__EXTERN_INLINE void jensen_outq(u64 b, unsigned long addr)
-{
-       jensen_set_hae(0);
-       *(vulp) ((addr << 7) + EISA_IO + 0x60) = b;
-       mb();
-}
-
-/*
- * Memory functions.
- */
-
-__EXTERN_INLINE u8 jensen_readb(const volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       long result;
-
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
-       result >>= (addr & 3) * 8;
-       return 0xffUL & result;
-}
-
-__EXTERN_INLINE u16 jensen_readw(const volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       long result;
-
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
-       result >>= (addr & 3) * 8;
-       return 0xffffUL & result;
-}
-
-__EXTERN_INLINE u32 jensen_readl(const volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
-}
-
-__EXTERN_INLINE u64 jensen_readq(const volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       unsigned long r0, r1;
-
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       addr = (addr << 7) + EISA_MEM + 0x60;
-       r0 = *(vuip) (addr);
-       r1 = *(vuip) (addr + (4 << 7));
-       return r1 << 32 | r0;
-}
-
-__EXTERN_INLINE void jensen_writeb(u8 b, volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       *(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
-}
-
-__EXTERN_INLINE void jensen_writew(u16 b, volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       *(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
-}
-
-__EXTERN_INLINE void jensen_writel(u32 b, volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       *(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
-}
-
-__EXTERN_INLINE void jensen_writeq(u64 b, volatile void __iomem *xaddr)
-{
-       unsigned long addr = (unsigned long) xaddr;
-       jensen_set_hae(addr);
-       addr &= JENSEN_HAE_MASK;
-       addr = (addr << 7) + EISA_MEM + 0x60;
-       *(vuip) (addr) = b;
-       *(vuip) (addr + (4 << 7)) = b >> 32;
-}
-
-__EXTERN_INLINE void __iomem *jensen_ioportmap(unsigned long addr)
-{
-       return (void __iomem *)addr;
-}
-
-__EXTERN_INLINE void __iomem *jensen_ioremap(unsigned long addr,
-                                            unsigned long size)
-{
-       return (void __iomem *)(addr + 0x100000000ul);
-}
-
-__EXTERN_INLINE int jensen_is_ioaddr(unsigned long addr)
-{
-       return (long)addr >= 0;
-}
-
-__EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
-{
-       return (unsigned long)addr >= 0x100000000ul;
-}
-
-/* New-style ioread interface.  All the routines are so ugly for Jensen
-   that it doesn't make sense to merge them.  */
-
-#define IOPORT(OS, NS)                                                 \
-__EXTERN_INLINE u##NS jensen_ioread##NS(const void __iomem *xaddr)     \
-{                                                                      \
-       if (jensen_is_mmio(xaddr))                                      \
-               return jensen_read##OS(xaddr - 0x100000000ul);          \
-       else                                                            \
-               return jensen_in##OS((unsigned long)xaddr);             \
-}                                                                      \
-__EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr)  \
-{                                                                      \
-       if (jensen_is_mmio(xaddr))                                      \
-               jensen_write##OS(b, xaddr - 0x100000000ul);             \
-       else                                                            \
-               jensen_out##OS(b, (unsigned long)xaddr);                \
-}
-
-IOPORT(b, 8)
-IOPORT(w, 16)
-IOPORT(l, 32)
-IOPORT(q, 64)
-
-#undef IOPORT
-
-#undef vuip
-#undef vulp
-
-#undef __IO_PREFIX
-#define __IO_PREFIX            jensen
-#define jensen_trivial_rw_bw   0
-#define jensen_trivial_rw_lq   0
-#define jensen_trivial_io_bw   0
-#define jensen_trivial_io_lq   0
-#define jensen_trivial_iounmap 1
-#include <asm/io_trivial.h>
-
-#ifdef __IO_EXTERN_INLINE
-#undef __EXTERN_INLINE
-#undef __IO_EXTERN_INLINE
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* __ALPHA_JENSEN_H */
index 8623f995d34c632fe325067dbeae9a415644b18c..490fc880bb3f8a3acec325c36899800dbcd7733c 100644 (file)
@@ -72,15 +72,6 @@ struct alpha_machine_vector
        int (*mv_is_ioaddr)(unsigned long);
        int (*mv_is_mmio)(const volatile void __iomem *);
 
-       void (*mv_switch_mm)(struct mm_struct *, struct mm_struct *,
-                            struct task_struct *);
-       void (*mv_activate_mm)(struct mm_struct *, struct mm_struct *);
-
-       void (*mv_flush_tlb_current)(struct mm_struct *);
-       void (*mv_flush_tlb_current_page)(struct mm_struct * mm,
-                                         struct vm_area_struct *vma,
-                                         unsigned long addr);
-
        void (*update_irq_hw)(unsigned long, unsigned long, int);
        void (*ack_irq)(unsigned long);
        void (*device_interrupt)(unsigned long vector);
index 29a3e3a1f02bec05e1c3f819330dbbf48bc84c5b..eee8fe836a59e68a6e5379511bd1d155e2cfff4f 100644 (file)
@@ -71,9 +71,7 @@ __reload_thread(struct pcb_struct *pcb)
 #ifdef CONFIG_ALPHA_GENERIC
 # define MAX_ASN       (alpha_mv.max_asn)
 #else
-# ifdef CONFIG_ALPHA_EV4
-#  define MAX_ASN      EV4_MAX_ASN
-# elif defined(CONFIG_ALPHA_EV5)
+# if defined(CONFIG_ALPHA_EV56)
 #  define MAX_ASN      EV5_MAX_ASN
 # else
 #  define MAX_ASN      EV6_MAX_ASN
@@ -162,26 +160,6 @@ ev5_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
        task_thread_info(next)->pcb.asn = mmc & HARDWARE_ASN_MASK;
 }
 
-__EXTERN_INLINE void
-ev4_switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
-             struct task_struct *next)
-{
-       /* As described, ASN's are broken for TLB usage.  But we can
-          optimize for switching between threads -- if the mm is
-          unchanged from current we needn't flush.  */
-       /* ??? May not be needed because EV4 PALcode recognizes that
-          ASN's are broken and does a tbiap itself on swpctx, under
-          the "Must set ASN or flush" rule.  At least this is true
-          for a 1992 SRM, reports Joseph Martin (jmartin@hlo.dec.com).
-          I'm going to leave this here anyway, just to Be Sure.  -- r~  */
-       if (prev_mm != next_mm)
-               tbiap();
-
-       /* Do continue to allocate ASNs, because we can still use them
-          to avoid flushing the icache.  */
-       ev5_switch_mm(prev_mm, next_mm, next);
-}
-
 extern void __load_new_mm_context(struct mm_struct *);
 asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
                              long cause, struct pt_regs *regs);
@@ -209,25 +187,8 @@ ev5_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
        __load_new_mm_context(next_mm);
 }
 
-__EXTERN_INLINE void
-ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
-{
-       __load_new_mm_context(next_mm);
-       tbiap();
-}
-
-#ifdef CONFIG_ALPHA_GENERIC
-# define switch_mm(a,b,c)      alpha_mv.mv_switch_mm((a),(b),(c))
-# define activate_mm(x,y)      alpha_mv.mv_activate_mm((x),(y))
-#else
-# ifdef CONFIG_ALPHA_EV4
-#  define switch_mm(a,b,c)     ev4_switch_mm((a),(b),(c))
-#  define activate_mm(x,y)     ev4_activate_mm((x),(y))
-# else
-#  define switch_mm(a,b,c)     ev5_switch_mm((a),(b),(c))
-#  define activate_mm(x,y)     ev5_activate_mm((x),(y))
-# endif
-#endif
+#define switch_mm(a,b,c)       ev5_switch_mm((a),(b),(c))
+#define activate_mm(x,y)       ev5_activate_mm((x),(y))
 
 #define init_new_context init_new_context
 static inline int
index ca2c5c30b22ea78a4591a218732b4ad7c7864e17..798d0bdb11f9e196a3926f89170f8a09c7f25615 100644 (file)
@@ -15,10 +15,7 @@ enum implver_enum {
    (enum implver_enum) __implver; })
 #else
 /* Try to eliminate some dead code.  */
-#ifdef CONFIG_ALPHA_EV4
-#define implver() IMPLVER_EV4
-#endif
-#ifdef CONFIG_ALPHA_EV5
+#ifdef CONFIG_ALPHA_EV56
 #define implver() IMPLVER_EV5
 #endif
 #if defined(CONFIG_ALPHA_EV6)
index 94dc37cf873a7515c350ce27d6f290031636819d..ba4b359d6c395de6766b51379c6a6e69977af695 100644 (file)
 extern void __load_new_mm_context(struct mm_struct *);
 
 
-/* Use a few helper functions to hide the ugly broken ASN
-   numbers on early Alphas (ev4 and ev45).  */
-
-__EXTERN_INLINE void
-ev4_flush_tlb_current(struct mm_struct *mm)
-{
-       __load_new_mm_context(mm);
-       tbiap();
-}
-
 __EXTERN_INLINE void
 ev5_flush_tlb_current(struct mm_struct *mm)
 {
@@ -34,19 +24,6 @@ ev5_flush_tlb_current(struct mm_struct *mm)
    careful about the icache here, there is no way to invalidate a
    specific icache page.  */
 
-__EXTERN_INLINE void
-ev4_flush_tlb_current_page(struct mm_struct * mm,
-                          struct vm_area_struct *vma,
-                          unsigned long addr)
-{
-       int tbi_flag = 2;
-       if (vma->vm_flags & VM_EXEC) {
-               __load_new_mm_context(mm);
-               tbi_flag = 3;
-       }
-       tbi(tbi_flag, addr);
-}
-
 __EXTERN_INLINE void
 ev5_flush_tlb_current_page(struct mm_struct * mm,
                           struct vm_area_struct *vma,
@@ -59,18 +36,8 @@ ev5_flush_tlb_current_page(struct mm_struct * mm,
 }
 
 
-#ifdef CONFIG_ALPHA_GENERIC
-# define flush_tlb_current             alpha_mv.mv_flush_tlb_current
-# define flush_tlb_current_page                alpha_mv.mv_flush_tlb_current_page
-#else
-# ifdef CONFIG_ALPHA_EV4
-#  define flush_tlb_current            ev4_flush_tlb_current
-#  define flush_tlb_current_page       ev4_flush_tlb_current_page
-# else
-#  define flush_tlb_current            ev5_flush_tlb_current
-#  define flush_tlb_current_page       ev5_flush_tlb_current_page
-# endif
-#endif
+#define flush_tlb_current      ev5_flush_tlb_current
+#define flush_tlb_current_page ev5_flush_tlb_current_page
 
 #ifdef __MMU_EXTERN_INLINE
 #undef __EXTERN_INLINE
index c32c2584c0b72c73fdbea8002c974a75ed1076c2..ef295cbb797cebb7799e237d58f1f58e0545c4d0 100644 (file)
@@ -96,9 +96,6 @@ struct __large_struct { unsigned long buf[100]; };
                : "=r"(__gu_val), "=r"(__gu_err)        \
                : "m"(__m(addr)), "1"(__gu_err))
 
-#ifdef __alpha_bwx__
-/* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
-
 #define __get_user_16(addr)                            \
        __asm__("1: ldwu %0,%2\n"                       \
        "2:\n"                                          \
@@ -112,33 +109,6 @@ struct __large_struct { unsigned long buf[100]; };
        EXC(1b,2b,%0,%1)                                \
                : "=r"(__gu_val), "=r"(__gu_err)        \
                : "m"(__m(addr)), "1"(__gu_err))
-#else
-/* Unfortunately, we can't get an unaligned access trap for the sub-word
-   load, so we have to do a general unaligned operation.  */
-
-#define __get_user_16(addr)                                            \
-{                                                                      \
-       long __gu_tmp;                                                  \
-       __asm__("1: ldq_u %0,0(%3)\n"                                   \
-       "2:     ldq_u %1,1(%3)\n"                                       \
-       "       extwl %0,%3,%0\n"                                       \
-       "       extwh %1,%3,%1\n"                                       \
-       "       or %0,%1,%0\n"                                          \
-       "3:\n"                                                          \
-       EXC(1b,3b,%0,%2)                                                \
-       EXC(2b,3b,%0,%2)                                                \
-               : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err)      \
-               : "r"(addr), "2"(__gu_err));                            \
-}
-
-#define __get_user_8(addr)                                             \
-       __asm__("1: ldq_u %0,0(%2)\n"                                   \
-       "       extbl %0,%2,%0\n"                                       \
-       "2:\n"                                                          \
-       EXC(1b,2b,%0,%1)                                                \
-               : "=&r"(__gu_val), "=r"(__gu_err)                       \
-               : "r"(addr), "1"(__gu_err))
-#endif
 
 extern void __put_user_unknown(void);
 
@@ -192,9 +162,6 @@ __asm__ __volatile__("1: stl %r2,%1\n"                              \
                : "=r"(__pu_err)                                \
                : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
 
-#ifdef __alpha_bwx__
-/* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
-
 #define __put_user_16(x, addr)                                 \
 __asm__ __volatile__("1: stw %r2,%1\n"                         \
        "2:\n"                                                  \
@@ -208,53 +175,6 @@ __asm__ __volatile__("1: stb %r2,%1\n"                             \
        EXC(1b,2b,$31,%0)                                       \
                : "=r"(__pu_err)                                \
                : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
-#else
-/* Unfortunately, we can't get an unaligned access trap for the sub-word
-   write, so we have to do a general unaligned operation.  */
-
-#define __put_user_16(x, addr)                                 \
-{                                                              \
-       long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4;        \
-       __asm__ __volatile__(                                   \
-       "1:     ldq_u %2,1(%5)\n"                               \
-       "2:     ldq_u %1,0(%5)\n"                               \
-       "       inswh %6,%5,%4\n"                               \
-       "       inswl %6,%5,%3\n"                               \
-       "       mskwh %2,%5,%2\n"                               \
-       "       mskwl %1,%5,%1\n"                               \
-       "       or %2,%4,%2\n"                                  \
-       "       or %1,%3,%1\n"                                  \
-       "3:     stq_u %2,1(%5)\n"                               \
-       "4:     stq_u %1,0(%5)\n"                               \
-       "5:\n"                                                  \
-       EXC(1b,5b,$31,%0)                                       \
-       EXC(2b,5b,$31,%0)                                       \
-       EXC(3b,5b,$31,%0)                                       \
-       EXC(4b,5b,$31,%0)                                       \
-               : "=r"(__pu_err), "=&r"(__pu_tmp1),             \
-                 "=&r"(__pu_tmp2), "=&r"(__pu_tmp3),           \
-                 "=&r"(__pu_tmp4)                              \
-               : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); \
-}
-
-#define __put_user_8(x, addr)                                  \
-{                                                              \
-       long __pu_tmp1, __pu_tmp2;                              \
-       __asm__ __volatile__(                                   \
-       "1:     ldq_u %1,0(%4)\n"                               \
-       "       insbl %3,%4,%2\n"                               \
-       "       mskbl %1,%4,%1\n"                               \
-       "       or %1,%2,%1\n"                                  \
-       "2:     stq_u %1,0(%4)\n"                               \
-       "3:\n"                                                  \
-       EXC(1b,3b,$31,%0)                                       \
-       EXC(2b,3b,$31,%0)                                       \
-               : "=r"(__pu_err),                               \
-                 "=&r"(__pu_tmp1), "=&r"(__pu_tmp2)            \
-               : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); \
-}
-#endif
-
 
 /*
  * Complex access routines
index 4c347a8454c7023a7911fe2e73ce137760e6a533..919931cb5b63d2b2b25d241123881bb888f2a1d2 100644 (file)
@@ -13,6 +13,7 @@
 #define VT_BUF_HAVE_RW
 #define VT_BUF_HAVE_MEMSETW
 #define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
 
 static inline void scr_writew(u16 val, volatile u16 *addr)
 {
@@ -40,6 +41,7 @@ static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
 
 /* Do not trust that the usage will be correct; analyze the arguments.  */
 extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
+extern void scr_memmovew(u16 *d, const u16 *s, unsigned int count);
 
 /* ??? These are currently only used for downloading character sets.  As
    such, they don't need memory barriers.  Is this all they are intended
index 0e00c0e13374cef58998369c6f59f525a6449844..8c03740966b49f8384d537d26664e9717a454ef8 100644 (file)
 #define __kernel_ldwu(mem)     (mem)
 #define __kernel_stb(val,mem)  ((mem) = (val))
 #define __kernel_stw(val,mem)  ((mem) = (val))
-#else
-#define __kernel_ldbu(mem)                             \
-  ({ unsigned char __kir;                              \
-     __asm__(".arch ev56;                              \
-             ldbu %0,%1" : "=r"(__kir) : "m"(mem));    \
-     __kir; })
-#define __kernel_ldwu(mem)                             \
-  ({ unsigned short __kir;                             \
-     __asm__(".arch ev56;                              \
-             ldwu %0,%1" : "=r"(__kir) : "m"(mem));    \
-     __kir; })
-#define __kernel_stb(val,mem)                          \
-  __asm__(".arch ev56;                                 \
-          stb %1,%0" : "=m"(mem) : "r"(val))
-#define __kernel_stw(val,mem)                          \
-  __asm__(".arch ev56;                                 \
-          stw %1,%0" : "=m"(mem) : "r"(val))
 #endif
 
-
 #endif /* _UAPI__ALPHA_COMPILER_H */
index fb4efec7cbc74147fdd29159ce7d95d8289437d4..b6c862dff1f647fb891188c125241bbc00a2adc7 100644 (file)
@@ -22,14 +22,14 @@ obj-$(CONFIG_AUDIT) += audit.o
 
 ifdef CONFIG_ALPHA_GENERIC
 
-obj-y   += core_apecs.o core_cia.o core_irongate.o core_lca.o \
+obj-y   += core_cia.o core_irongate.o \
            core_mcpcia.o core_polaris.o core_t2.o \
            core_tsunami.o
 
-obj-y   += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
-           sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+obj-y   += sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eiger.o \
+           sys_miata.o sys_mikasa.o sys_nautilus.o \
            sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
-           sys_sable.o sys_sio.o sys_sx164.o sys_takara.o
+           sys_sable.o sys_sx164.o sys_takara.o
 
 ifndef CONFIG_ALPHA_LEGACY_START_ADDRESS
 obj-y   += core_marvel.o core_titan.o core_wildfire.o
@@ -48,10 +48,8 @@ else
 obj-$(CONFIG_ALPHA_SRM)                += srmcons.o
 
 # Core logic support
-obj-$(CONFIG_ALPHA_APECS)      += core_apecs.o
 obj-$(CONFIG_ALPHA_CIA)                += core_cia.o
 obj-$(CONFIG_ALPHA_IRONGATE)   += core_irongate.o
-obj-$(CONFIG_ALPHA_LCA)                += core_lca.o
 obj-$(CONFIG_ALPHA_MARVEL)     += core_marvel.o gct.o
 obj-$(CONFIG_ALPHA_MCPCIA)     += core_mcpcia.o
 obj-$(CONFIG_ALPHA_POLARIS)    += core_polaris.o
@@ -62,12 +60,6 @@ obj-$(CONFIG_ALPHA_WILDFIRE) += core_wildfire.o
 
 # Board support
 obj-$(CONFIG_ALPHA_ALCOR)      += sys_alcor.o irq_i8259.o irq_srm.o
-obj-$(CONFIG_ALPHA_CABRIOLET)  += sys_cabriolet.o irq_i8259.o irq_srm.o \
-                                  pc873xx.o
-obj-$(CONFIG_ALPHA_EB164)      += sys_cabriolet.o irq_i8259.o irq_srm.o \
-                                  pc873xx.o
-obj-$(CONFIG_ALPHA_EB66P)      += sys_cabriolet.o irq_i8259.o irq_srm.o \
-                                  pc873xx.o
 obj-$(CONFIG_ALPHA_LX164)      += sys_cabriolet.o irq_i8259.o irq_srm.o \
                                   smc37c93x.o
 obj-$(CONFIG_ALPHA_PC164)      += sys_cabriolet.o irq_i8259.o irq_srm.o \
@@ -75,10 +67,7 @@ obj-$(CONFIG_ALPHA_PC164)    += sys_cabriolet.o irq_i8259.o irq_srm.o \
 obj-$(CONFIG_ALPHA_DP264)      += sys_dp264.o irq_i8259.o es1888.o smc37c669.o
 obj-$(CONFIG_ALPHA_SHARK)      += sys_dp264.o irq_i8259.o es1888.o smc37c669.o
 obj-$(CONFIG_ALPHA_TITAN)      += sys_titan.o irq_i8259.o smc37c669.o
-obj-$(CONFIG_ALPHA_EB64P)      += sys_eb64p.o irq_i8259.o
-obj-$(CONFIG_ALPHA_EB66)       += sys_eb64p.o irq_i8259.o
 obj-$(CONFIG_ALPHA_EIGER)      += sys_eiger.o irq_i8259.o
-obj-$(CONFIG_ALPHA_JENSEN)     += sys_jensen.o pci-noop.o irq_i8259.o
 obj-$(CONFIG_ALPHA_MARVEL)     += sys_marvel.o 
 obj-$(CONFIG_ALPHA_MIATA)      += sys_miata.o irq_pyxis.o irq_i8259.o \
                                   es1888.o smc37c669.o
@@ -89,12 +78,6 @@ obj-$(CONFIG_ALPHA_RAWHIDE)  += sys_rawhide.o irq_i8259.o
 obj-$(CONFIG_ALPHA_RUFFIAN)    += sys_ruffian.o irq_pyxis.o irq_i8259.o
 obj-$(CONFIG_ALPHA_RX164)      += sys_rx164.o irq_i8259.o
 obj-$(CONFIG_ALPHA_SABLE)      += sys_sable.o
-obj-$(CONFIG_ALPHA_LYNX)       += sys_sable.o
-obj-$(CONFIG_ALPHA_BOOK1)      += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_AVANTI)     += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_NONAME)     += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_P2K)                += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
-obj-$(CONFIG_ALPHA_XL)         += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o
 obj-$(CONFIG_ALPHA_SX164)      += sys_sx164.o irq_pyxis.o irq_i8259.o \
                                   irq_srm.o smc37c669.o
 obj-$(CONFIG_ALPHA_TAKARA)     += sys_takara.o irq_i8259.o pc873xx.o
index bf1eedd27cf751e1f521645fed753c9ff468a557..4cfeae42c79ac73f92908da10ce8f9da81154096 100644 (file)
 #include <linux/sched.h>
 #include <linux/ptrace.h>
 #include <linux/kbuild.h>
-#include <asm/io.h>
+#include <asm/machvec.h>
 
 static void __used foo(void)
 {
-       DEFINE(TI_TASK, offsetof(struct thread_info, task));
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
-       DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
        DEFINE(TI_FP, offsetof(struct thread_info, fp));
        DEFINE(TI_STATUS, offsetof(struct thread_info, status));
        BLANK();
 
-        DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
-        DEFINE(TASK_CRED, offsetof(struct task_struct, cred));
-        DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
-        DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader));
-        DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
-        BLANK();
-
-        DEFINE(CRED_UID,  offsetof(struct cred, uid));
-        DEFINE(CRED_EUID, offsetof(struct cred, euid));
-        DEFINE(CRED_GID,  offsetof(struct cred, gid));
-        DEFINE(CRED_EGID, offsetof(struct cred, egid));
-        BLANK();
-
        DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
-       DEFINE(PT_PTRACED, PT_PTRACED);
-       DEFINE(CLONE_VM, CLONE_VM);
-       DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
-       DEFINE(SIGCHLD, SIGCHLD);
        BLANK();
 
        DEFINE(HAE_CACHE, offsetof(struct alpha_machine_vector, hae_cache));
index 08cc10d7fa17d053127af0c882c7a51c0f0a3b46..e8c51089325fe9e2b7cc8dd5309144024372adaf 100644 (file)
@@ -1,6 +1,7 @@
 
 #include <asm/hwrpb.h>
 #include <linux/device.h>
+#include <linux/cpu.h>
 
 
 #ifdef CONFIG_SYSFS
index 5476279329a62ed320631f5ec0b90c0f443971cb..4193f76e9633abc7659d79a017a1f2e27e8bdde6 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/machvec.h>
 
 #include "pci_impl.h"
+#include "proto.h"
 
 #ifdef CONFIG_VGA_HOSE
 
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
deleted file mode 100644 (file)
index 6df765f..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/core_apecs.c
- *
- * Rewritten for Apecs from the lca.c from:
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- *
- * Code common to all APECS core logic chips.
- */
-
-#define __EXTERN_INLINE inline
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#undef __EXTERN_INLINE
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/ptrace.h>
-#include <asm/smp.h>
-#include <asm/mce.h>
-
-#include "proto.h"
-#include "pci_impl.h"
-
-/*
- * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
- * One plausible explanation is that the i/o controller does not properly
- * handle the system transaction.  Another involves timing.  Ho hum.
- */
-
-/*
- * BIOS32-style PCI interface:
- */
-
-#define DEBUG_CONFIG 0
-
-#if DEBUG_CONFIG
-# define DBGC(args)    printk args
-#else
-# define DBGC(args)
-#endif
-
-#define vuip   volatile unsigned int  *
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the APECS_HAXR2 register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-
-static int
-mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
-            unsigned long *pci_addr, unsigned char *type1)
-{
-       unsigned long addr;
-       u8 bus = pbus->number;
-
-       DBGC(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x,"
-             " pci_addr=0x%p, type1=0x%p)\n",
-             bus, device_fn, where, pci_addr, type1));
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-
-               /* type 0 configuration cycle: */
-
-               if (device > 20) {
-                       DBGC(("mk_conf_addr: device (%d) > 20, returning -1\n",
-                             device));
-                       return -1;
-               }
-
-               *type1 = 0;
-               addr = (device_fn << 8) | (where);
-       } else {
-               /* type 1 configuration cycle: */
-               *type1 = 1;
-               addr = (bus << 16) | (device_fn << 8) | (where);
-       }
-       *pci_addr = addr;
-       DBGC(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
-       return 0;
-}
-
-static unsigned int
-conf_read(unsigned long addr, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0, value;
-       unsigned int haxr2 = 0;
-
-       local_irq_save(flags);  /* avoid getting hit by machine check */
-
-       DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
-
-       /* Reset status register to avoid losing errors.  */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       *(vuip)APECS_IOC_DCSR = stat0;
-       mb();
-       DBGC(("conf_read: APECS DCSR was 0x%x\n", stat0));
-
-       /* If Type1 access, must set HAE #2. */
-       if (type1) {
-               haxr2 = *(vuip)APECS_IOC_HAXR2;
-               mb();
-               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
-               DBGC(("conf_read: TYPE1 access\n"));
-       }
-
-       draina();
-       mcheck_expected(0) = 1;
-       mcheck_taken(0) = 0;
-       mb();
-
-       /* Access configuration space.  */
-
-       /* Some SRMs step on these registers during a machine check.  */
-       asm volatile("ldl %0,%1; mb; mb" : "=r"(value) : "m"(*(vuip)addr)
-                    : "$9", "$10", "$11", "$12", "$13", "$14", "memory");
-
-       if (mcheck_taken(0)) {
-               mcheck_taken(0) = 0;
-               value = 0xffffffffU;
-               mb();
-       }
-       mcheck_expected(0) = 0;
-       mb();
-
-#if 1
-       /*
-        * david.rusling@reo.mts.dec.com.  This code is needed for the
-        * EB64+ as it does not generate a machine check (why I don't
-        * know).  When we build kernels for one particular platform
-        * then we can make this conditional on the type.
-        */
-       draina();
-
-       /* Now look for any errors.  */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       DBGC(("conf_read: APECS DCSR after read 0x%x\n", stat0));
-
-       /* Is any error bit set? */
-       if (stat0 & 0xffe0U) {
-               /* If not NDEV, print status.  */
-               if (!(stat0 & 0x0800)) {
-                       printk("apecs.c:conf_read: got stat0=%x\n", stat0);
-               }
-
-               /* Reset error status.  */
-               *(vuip)APECS_IOC_DCSR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-               value = 0xffffffff;
-       }
-#endif
-
-       /* If Type1 access, must reset HAE #2 so normal IO space ops work.  */
-       if (type1) {
-               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
-               mb();
-       }
-       local_irq_restore(flags);
-
-       return value;
-}
-
-static void
-conf_write(unsigned long addr, unsigned int value, unsigned char type1)
-{
-       unsigned long flags;
-       unsigned int stat0;
-       unsigned int haxr2 = 0;
-
-       local_irq_save(flags);  /* avoid getting hit by machine check */
-
-       /* Reset status register to avoid losing errors.  */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-       *(vuip)APECS_IOC_DCSR = stat0;
-       mb();
-
-       /* If Type1 access, must set HAE #2. */
-       if (type1) {
-               haxr2 = *(vuip)APECS_IOC_HAXR2;
-               mb();
-               *(vuip)APECS_IOC_HAXR2 = haxr2 | 1;
-       }
-
-       draina();
-       mcheck_expected(0) = 1;
-       mb();
-
-       /* Access configuration space.  */
-       *(vuip)addr = value;
-       mb();
-       mb();  /* magic */
-       mcheck_expected(0) = 0;
-       mb();
-
-#if 1
-       /*
-        * david.rusling@reo.mts.dec.com.  This code is needed for the
-        * EB64+ as it does not generate a machine check (why I don't
-        * know).  When we build kernels for one particular platform
-        * then we can make this conditional on the type.
-        */
-       draina();
-
-       /* Now look for any errors.  */
-       stat0 = *(vuip)APECS_IOC_DCSR;
-
-       /* Is any error bit set? */
-       if (stat0 & 0xffe0U) {
-               /* If not NDEV, print status.  */
-               if (!(stat0 & 0x0800)) {
-                       printk("apecs.c:conf_write: got stat0=%x\n", stat0);
-               }
-
-               /* Reset error status.  */
-               *(vuip)APECS_IOC_DCSR = stat0;
-               mb();
-               wrmces(0x7);                    /* reset machine check */
-       }
-#endif
-
-       /* If Type1 access, must reset HAE #2 so normal IO space ops work.  */
-       if (type1) {
-               *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1;
-               mb();
-       }
-       local_irq_restore(flags);
-}
-
-static int
-apecs_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-                 int size, u32 *value)
-{
-       unsigned long addr, pci_addr;
-       unsigned char type1;
-       long mask;
-       int shift;
-
-       if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       mask = (size - 1) * 8;
-       shift = (where & 3) * 8;
-       addr = (pci_addr << 5) + mask + APECS_CONF;
-       *value = conf_read(addr, type1) >> (shift);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-apecs_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-                  int size, u32 value)
-{
-       unsigned long addr, pci_addr;
-       unsigned char type1;
-       long mask;
-
-       if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       mask = (size - 1) * 8;
-       addr = (pci_addr << 5) + mask + APECS_CONF;
-       conf_write(addr, value << ((where & 3) * 8), type1);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops apecs_pci_ops = 
-{
-       .read =         apecs_read_config,
-       .write =        apecs_write_config,
-};
-\f
-void
-apecs_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
-{
-       wmb();
-       *(vip)APECS_IOC_TBIA = 0;
-       mb();
-}
-\f
-void __init
-apecs_init_arch(void)
-{
-       struct pci_controller *hose;
-
-       /*
-        * Create our single hose.
-        */
-
-       pci_isa_hose = hose = alloc_pci_controller();
-       hose->io_space = &ioport_resource;
-       hose->mem_space = &iomem_resource;
-       hose->index = 0;
-
-       hose->sparse_mem_base = APECS_SPARSE_MEM - IDENT_ADDR;
-       hose->dense_mem_base = APECS_DENSE_MEM - IDENT_ADDR;
-       hose->sparse_io_base = APECS_IO - IDENT_ADDR;
-       hose->dense_io_base = 0;
-
-       /*
-        * Set up the PCI to main memory translation windows.
-        *
-        * Window 1 is direct access 1GB at 1GB
-        * Window 2 is scatter-gather 8MB at 8MB (for isa)
-        */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
-                                      SMP_CACHE_BYTES);
-       hose->sg_pci = NULL;
-       __direct_map_base = 0x40000000;
-       __direct_map_size = 0x40000000;
-
-       *(vuip)APECS_IOC_PB1R = __direct_map_base | 0x00080000;
-       *(vuip)APECS_IOC_PM1R = (__direct_map_size - 1) & 0xfff00000U;
-       *(vuip)APECS_IOC_TB1R = 0;
-
-       *(vuip)APECS_IOC_PB2R = hose->sg_isa->dma_base | 0x000c0000;
-       *(vuip)APECS_IOC_PM2R = (hose->sg_isa->size - 1) & 0xfff00000;
-       *(vuip)APECS_IOC_TB2R = virt_to_phys(hose->sg_isa->ptes) >> 1;
-
-       apecs_pci_tbi(hose, 0, -1);
-
-       /*
-        * Finally, clear the HAXR2 register, which gets used
-        * for PCI Config Space accesses. That is the way
-        * we want to use it, and we do not want to depend on
-        * what ARC or SRM might have left behind...
-        */
-       *(vuip)APECS_IOC_HAXR2 = 0;
-       mb();
-}
-
-void
-apecs_pci_clr_err(void)
-{
-       unsigned int jd;
-
-       jd = *(vuip)APECS_IOC_DCSR;
-       if (jd & 0xffe0L) {
-               *(vuip)APECS_IOC_SEAR;
-               *(vuip)APECS_IOC_DCSR = jd | 0xffe1L;
-               mb();
-               *(vuip)APECS_IOC_DCSR;
-       }
-       *(vuip)APECS_IOC_TBIA = (unsigned int)APECS_IOC_TBIA;
-       mb();
-       *(vuip)APECS_IOC_TBIA;
-}
-
-void
-apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-       struct el_common *mchk_header;
-       struct el_apecs_procdata *mchk_procdata;
-       struct el_apecs_sysdata_mcheck *mchk_sysdata;
-
-       mchk_header = (struct el_common *)la_ptr;
-
-       mchk_procdata = (struct el_apecs_procdata *)
-               (la_ptr + mchk_header->proc_offset
-                - sizeof(mchk_procdata->paltemp));
-
-       mchk_sysdata = (struct el_apecs_sysdata_mcheck *)
-               (la_ptr + mchk_header->sys_offset);
-
-
-       /* Clear the error before any reporting.  */
-       mb();
-       mb(); /* magic */
-       draina();
-       apecs_pci_clr_err();
-       wrmces(0x7);            /* reset machine check pending flag */
-       mb();
-
-       process_mcheck_info(vector, la_ptr, "APECS",
-                           (mcheck_expected(0)
-                            && (mchk_sysdata->epic_dcsr & 0x0c00UL)));
-}
index 12926e9538b800813f6e1e35f29534016092a932..ca3d9c732b61df90714c5c0acfe651fa9e94ee61 100644 (file)
@@ -280,7 +280,7 @@ cia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
 #define CIA_BROKEN_TBIA_SIZE   1024
 
 /* Always called with interrupts disabled */
-void
+static void
 cia_pci_tbi_try2(struct pci_controller *hose,
                 dma_addr_t start, dma_addr_t end)
 {
@@ -576,7 +576,7 @@ struct
     } window[4];
 } saved_config __attribute((common));
 
-void
+static void
 cia_save_srm_settings(int is_pyxis)
 {
        int i;
@@ -602,7 +602,7 @@ cia_save_srm_settings(int is_pyxis)
        mb();
 }
 
-void
+static void
 cia_restore_srm_settings(void)
 {
        int i;
index 6b8ed12936b6f131c4276d2d1283d876d42846a6..05dc4c1b9074868c81867dcee7d2fa1541076f65 100644 (file)
@@ -226,7 +226,6 @@ albacore_init_arch(void)
        if (memtop > pci_mem) {
 #ifdef CONFIG_BLK_DEV_INITRD
                extern unsigned long initrd_start, initrd_end;
-               extern void *move_initrd(unsigned long);
 
                /* Move the initrd out of the way. */
                if (initrd_end && __pa(initrd_end) > pci_mem) {
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
deleted file mode 100644 (file)
index 57e0750..0000000
+++ /dev/null
@@ -1,517 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/core_lca.c
- *
- * Written by David Mosberger (davidm@cs.arizona.edu) with some code
- * taken from Dave Rusling's (david.rusling@reo.mts.dec.com) 32-bit
- * bios code.
- *
- * Code common to all LCA core logic chips.
- */
-
-#define __EXTERN_INLINE inline
-#include <asm/io.h>
-#include <asm/core_lca.h>
-#undef __EXTERN_INLINE
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-
-#include <asm/ptrace.h>
-#include <asm/irq_regs.h>
-#include <asm/smp.h>
-
-#include "proto.h"
-#include "pci_impl.h"
-
-
-/*
- * BIOS32-style PCI interface:
- */
-
-/*
- * Machine check reasons.  Defined according to PALcode sources
- * (osf.h and platform.h).
- */
-#define MCHK_K_TPERR           0x0080
-#define MCHK_K_TCPERR          0x0082
-#define MCHK_K_HERR            0x0084
-#define MCHK_K_ECC_C           0x0086
-#define MCHK_K_ECC_NC          0x0088
-#define MCHK_K_UNKNOWN         0x008A
-#define MCHK_K_CACKSOFT                0x008C
-#define MCHK_K_BUGCHECK                0x008E
-#define MCHK_K_OS_BUGCHECK     0x0090
-#define MCHK_K_DCPERR          0x0092
-#define MCHK_K_ICPERR          0x0094
-
-
-/*
- * Platform-specific machine-check reasons:
- */
-#define MCHK_K_SIO_SERR                0x204   /* all platforms so far */
-#define MCHK_K_SIO_IOCHK       0x206   /* all platforms so far */
-#define MCHK_K_DCSR            0x208   /* all but Noname */
-
-
-/*
- * Given a bus, device, and function number, compute resulting
- * configuration space address and setup the LCA_IOC_CONF register
- * accordingly.  It is therefore not safe to have concurrent
- * invocations to configuration space access routines, but there
- * really shouldn't be any need for this.
- *
- * Type 0:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | | | | | | | | | | | | | | |F|F|F|R|R|R|R|R|R|0|0|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:11   Device select bit.
- *     10:8    Function number
- *      7:2    Register number
- *
- * Type 1:
- *
- *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
- *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *     31:24   reserved
- *     23:16   bus number (8 bits = 128 possible buses)
- *     15:11   Device number (5 bits)
- *     10:8    function number
- *      7:2    register number
- *  
- * Notes:
- *     The function number selects which function of a multi-function device 
- *     (e.g., SCSI and Ethernet).
- * 
- *     The register selects a DWORD (32 bit) register offset.  Hence it
- *     doesn't get shifted by 2 bits as we want to "drop" the bottom two
- *     bits.
- */
-
-static int
-mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
-            unsigned long *pci_addr)
-{
-       unsigned long addr;
-       u8 bus = pbus->number;
-
-       if (bus == 0) {
-               int device = device_fn >> 3;
-               int func = device_fn & 0x7;
-
-               /* Type 0 configuration cycle.  */
-
-               if (device > 12) {
-                       return -1;
-               }
-
-               *(vulp)LCA_IOC_CONF = 0;
-               addr = (1 << (11 + device)) | (func << 8) | where;
-       } else {
-               /* Type 1 configuration cycle.  */
-               *(vulp)LCA_IOC_CONF = 1;
-               addr = (bus << 16) | (device_fn << 8) | where;
-       }
-       *pci_addr = addr;
-       return 0;
-}
-
-static unsigned int
-conf_read(unsigned long addr)
-{
-       unsigned long flags, code, stat0;
-       unsigned int value;
-
-       local_irq_save(flags);
-
-       /* Reset status register to avoid losing errors.  */
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       *(vulp)LCA_IOC_STAT0 = stat0;
-       mb();
-
-       /* Access configuration space.  */
-       value = *(vuip)addr;
-       draina();
-
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       if (stat0 & LCA_IOC_STAT0_ERR) {
-               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
-                       & LCA_IOC_STAT0_CODE_MASK);
-               if (code != 1) {
-                       printk("lca.c:conf_read: got stat0=%lx\n", stat0);
-               }
-
-               /* Reset error status.  */
-               *(vulp)LCA_IOC_STAT0 = stat0;
-               mb();
-
-               /* Reset machine check.  */
-               wrmces(0x7);
-
-               value = 0xffffffff;
-       }
-       local_irq_restore(flags);
-       return value;
-}
-
-static void
-conf_write(unsigned long addr, unsigned int value)
-{
-       unsigned long flags, code, stat0;
-
-       local_irq_save(flags);  /* avoid getting hit by machine check */
-
-       /* Reset status register to avoid losing errors.  */
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       *(vulp)LCA_IOC_STAT0 = stat0;
-       mb();
-
-       /* Access configuration space.  */
-       *(vuip)addr = value;
-       draina();
-
-       stat0 = *(vulp)LCA_IOC_STAT0;
-       if (stat0 & LCA_IOC_STAT0_ERR) {
-               code = ((stat0 >> LCA_IOC_STAT0_CODE_SHIFT)
-                       & LCA_IOC_STAT0_CODE_MASK);
-               if (code != 1) {
-                       printk("lca.c:conf_write: got stat0=%lx\n", stat0);
-               }
-
-               /* Reset error status.  */
-               *(vulp)LCA_IOC_STAT0 = stat0;
-               mb();
-
-               /* Reset machine check. */
-               wrmces(0x7);
-       }
-       local_irq_restore(flags);
-}
-
-static int
-lca_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 *value)
-{
-       unsigned long addr, pci_addr;
-       long mask;
-       int shift;
-
-       if (mk_conf_addr(bus, devfn, where, &pci_addr))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       shift = (where & 3) * 8;
-       mask = (size - 1) * 8;
-       addr = (pci_addr << 5) + mask + LCA_CONF;
-       *value = conf_read(addr) >> (shift);
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int 
-lca_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
-                u32 value)
-{
-       unsigned long addr, pci_addr;
-       long mask;
-
-       if (mk_conf_addr(bus, devfn, where, &pci_addr))
-               return PCIBIOS_DEVICE_NOT_FOUND;
-
-       mask = (size - 1) * 8;
-       addr = (pci_addr << 5) + mask + LCA_CONF;
-       conf_write(addr, value << ((where & 3) * 8));
-       return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops lca_pci_ops = 
-{
-       .read =         lca_read_config,
-       .write =        lca_write_config,
-};
-\f
-void
-lca_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
-{
-       wmb();
-       *(vulp)LCA_IOC_TBIA = 0;
-       mb();
-}
-\f
-void __init
-lca_init_arch(void)
-{
-       struct pci_controller *hose;
-
-       /*
-        * Create our single hose.
-        */
-
-       pci_isa_hose = hose = alloc_pci_controller();
-       hose->io_space = &ioport_resource;
-       hose->mem_space = &iomem_resource;
-       hose->index = 0;
-
-       hose->sparse_mem_base = LCA_SPARSE_MEM - IDENT_ADDR;
-       hose->dense_mem_base = LCA_DENSE_MEM - IDENT_ADDR;
-       hose->sparse_io_base = LCA_IO - IDENT_ADDR;
-       hose->dense_io_base = 0;
-
-       /*
-        * Set up the PCI to main memory translation windows.
-        *
-        * Mimic the SRM settings for the direct-map window.
-        *   Window 0 is scatter-gather 8MB at 8MB (for isa).
-        *   Window 1 is direct access 1GB at 1GB.
-        *
-        * Note that we do not try to save any of the DMA window CSRs
-        * before setting them, since we cannot read those CSRs on LCA.
-        */
-       hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000,
-                                      SMP_CACHE_BYTES);
-       hose->sg_pci = NULL;
-       __direct_map_base = 0x40000000;
-       __direct_map_size = 0x40000000;
-
-       *(vulp)LCA_IOC_W_BASE0 = hose->sg_isa->dma_base | (3UL << 32);
-       *(vulp)LCA_IOC_W_MASK0 = (hose->sg_isa->size - 1) & 0xfff00000;
-       *(vulp)LCA_IOC_T_BASE0 = virt_to_phys(hose->sg_isa->ptes);
-
-       *(vulp)LCA_IOC_W_BASE1 = __direct_map_base | (2UL << 32);
-       *(vulp)LCA_IOC_W_MASK1 = (__direct_map_size - 1) & 0xfff00000;
-       *(vulp)LCA_IOC_T_BASE1 = 0;
-
-       *(vulp)LCA_IOC_TB_ENA = 0x80;
-
-       lca_pci_tbi(hose, 0, -1);
-
-       /*
-        * Disable PCI parity for now.  The NCR53c810 chip has
-        * troubles meeting the PCI spec which results in
-        * data parity errors.
-        */
-       *(vulp)LCA_IOC_PAR_DIS = 1UL<<5;
-
-       /*
-        * Finally, set up for restoring the correct HAE if using SRM.
-        * Again, since we cannot read many of the CSRs on the LCA,
-        * one of which happens to be the HAE, we save the value that
-        * the SRM will expect...
-        */
-       if (alpha_using_srm)
-               srm_hae = 0x80000000UL;
-}
-
-/*
- * Constants used during machine-check handling.  I suppose these
- * could be moved into lca.h but I don't see much reason why anybody
- * else would want to use them.
- */
-
-#define ESR_EAV                (1UL<< 0)       /* error address valid */
-#define ESR_CEE                (1UL<< 1)       /* correctable error */
-#define ESR_UEE                (1UL<< 2)       /* uncorrectable error */
-#define ESR_WRE                (1UL<< 3)       /* write-error */
-#define ESR_SOR                (1UL<< 4)       /* error source */
-#define ESR_CTE                (1UL<< 7)       /* cache-tag error */
-#define ESR_MSE                (1UL<< 9)       /* multiple soft errors */
-#define ESR_MHE                (1UL<<10)       /* multiple hard errors */
-#define ESR_NXM                (1UL<<12)       /* non-existent memory */
-
-#define IOC_ERR                (  1<<4)        /* ioc logs an error */
-#define IOC_CMD_SHIFT  0
-#define IOC_CMD                (0xf<<IOC_CMD_SHIFT)
-#define IOC_CODE_SHIFT 8
-#define IOC_CODE       (0xf<<IOC_CODE_SHIFT)
-#define IOC_LOST       (  1<<5)
-#define IOC_P_NBR      ((__u32) ~((1<<13) - 1))
-
-static void
-mem_error(unsigned long esr, unsigned long ear)
-{
-       printk("    %s %s error to %s occurred at address %x\n",
-              ((esr & ESR_CEE) ? "Correctable" :
-               (esr & ESR_UEE) ? "Uncorrectable" : "A"),
-              (esr & ESR_WRE) ? "write" : "read",
-              (esr & ESR_SOR) ? "memory" : "b-cache",
-              (unsigned) (ear & 0x1ffffff8));
-       if (esr & ESR_CTE) {
-               printk("    A b-cache tag parity error was detected.\n");
-       }
-       if (esr & ESR_MSE) {
-               printk("    Several other correctable errors occurred.\n");
-       }
-       if (esr & ESR_MHE) {
-               printk("    Several other uncorrectable errors occurred.\n");
-       }
-       if (esr & ESR_NXM) {
-               printk("    Attempted to access non-existent memory.\n");
-       }
-}
-
-static void
-ioc_error(__u32 stat0, __u32 stat1)
-{
-       static const char * const pci_cmd[] = {
-               "Interrupt Acknowledge", "Special", "I/O Read", "I/O Write",
-               "Rsvd 1", "Rsvd 2", "Memory Read", "Memory Write", "Rsvd3",
-               "Rsvd4", "Configuration Read", "Configuration Write",
-               "Memory Read Multiple", "Dual Address", "Memory Read Line",
-               "Memory Write and Invalidate"
-       };
-       static const char * const err_name[] = {
-               "exceeded retry limit", "no device", "bad data parity",
-               "target abort", "bad address parity", "page table read error",
-               "invalid page", "data error"
-       };
-       unsigned code = (stat0 & IOC_CODE) >> IOC_CODE_SHIFT;
-       unsigned cmd  = (stat0 & IOC_CMD)  >> IOC_CMD_SHIFT;
-
-       printk("    %s initiated PCI %s cycle to address %x"
-              " failed due to %s.\n",
-              code > 3 ? "PCI" : "CPU", pci_cmd[cmd], stat1, err_name[code]);
-
-       if (code == 5 || code == 6) {
-               printk("    (Error occurred at PCI memory address %x.)\n",
-                      (stat0 & ~IOC_P_NBR));
-       }
-       if (stat0 & IOC_LOST) {
-               printk("    Other PCI errors occurred simultaneously.\n");
-       }
-}
-
-void
-lca_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-       const char * reason;
-       union el_lca el;
-
-       el.c = (struct el_common *) la_ptr;
-
-       wrmces(rdmces());       /* reset machine check pending flag */
-
-       printk(KERN_CRIT "LCA machine check: vector=%#lx pc=%#lx code=%#x\n",
-              vector, get_irq_regs()->pc, (unsigned int) el.c->code);
-
-       /*
-        * The first quadword after the common header always seems to
-        * be the machine check reason---don't know why this isn't
-        * part of the common header instead.  In the case of a long
-        * logout frame, the upper 32 bits is the machine check
-        * revision level, which we ignore for now.
-        */
-       switch ((unsigned int) el.c->code) {
-       case MCHK_K_TPERR:      reason = "tag parity error"; break;
-       case MCHK_K_TCPERR:     reason = "tag control parity error"; break;
-       case MCHK_K_HERR:       reason = "access to non-existent memory"; break;
-       case MCHK_K_ECC_C:      reason = "correctable ECC error"; break;
-       case MCHK_K_ECC_NC:     reason = "non-correctable ECC error"; break;
-       case MCHK_K_CACKSOFT:   reason = "MCHK_K_CACKSOFT"; break;
-       case MCHK_K_BUGCHECK:   reason = "illegal exception in PAL mode"; break;
-       case MCHK_K_OS_BUGCHECK: reason = "callsys in kernel mode"; break;
-       case MCHK_K_DCPERR:     reason = "d-cache parity error"; break;
-       case MCHK_K_ICPERR:     reason = "i-cache parity error"; break;
-       case MCHK_K_SIO_SERR:   reason = "SIO SERR occurred on PCI bus"; break;
-       case MCHK_K_SIO_IOCHK:  reason = "SIO IOCHK occurred on ISA bus"; break;
-       case MCHK_K_DCSR:       reason = "MCHK_K_DCSR"; break;
-       case MCHK_K_UNKNOWN:
-       default:                reason = "unknown"; break;
-       }
-
-       switch (el.c->size) {
-       case sizeof(struct el_lca_mcheck_short):
-               printk(KERN_CRIT
-                      "  Reason: %s (short frame%s, dc_stat=%#lx):\n",
-                      reason, el.c->retry ? ", retryable" : "",
-                      el.s->dc_stat);
-               if (el.s->esr & ESR_EAV) {
-                       mem_error(el.s->esr, el.s->ear);
-               }
-               if (el.s->ioc_stat0 & IOC_ERR) {
-                       ioc_error(el.s->ioc_stat0, el.s->ioc_stat1);
-               }
-               break;
-
-       case sizeof(struct el_lca_mcheck_long):
-               printk(KERN_CRIT "  Reason: %s (long frame%s):\n",
-                      reason, el.c->retry ? ", retryable" : "");
-               printk(KERN_CRIT
-                      "    reason: %#lx  exc_addr: %#lx  dc_stat: %#lx\n", 
-                      el.l->pt[0], el.l->exc_addr, el.l->dc_stat);
-               printk(KERN_CRIT "    car: %#lx\n", el.l->car);
-               if (el.l->esr & ESR_EAV) {
-                       mem_error(el.l->esr, el.l->ear);
-               }
-               if (el.l->ioc_stat0 & IOC_ERR) {
-                       ioc_error(el.l->ioc_stat0, el.l->ioc_stat1);
-               }
-               break;
-
-       default:
-               printk(KERN_CRIT "  Unknown errorlog size %d\n", el.c->size);
-       }
-
-       /* Dump the logout area to give all info.  */
-#ifdef CONFIG_VERBOSE_MCHECK
-       if (alpha_verbose_mcheck > 1) {
-               unsigned long * ptr = (unsigned long *) la_ptr;
-               long i;
-               for (i = 0; i < el.c->size / sizeof(long); i += 2) {
-                       printk(KERN_CRIT " +%8lx %016lx %016lx\n",
-                              i*sizeof(long), ptr[i], ptr[i+1]);
-               }
-       }
-#endif /* CONFIG_VERBOSE_MCHECK */
-}
-
-/*
- * The following routines are needed to support the SPEED changing
- * necessary to successfully manage the thermal problem on the AlphaBook1.
- */
-
-void
-lca_clock_print(void)
-{
-        long    pmr_reg;
-
-        pmr_reg = LCA_READ_PMR;
-
-        printk("Status of clock control:\n");
-        printk("\tPrimary clock divisor\t0x%lx\n", LCA_GET_PRIMARY(pmr_reg));
-        printk("\tOverride clock divisor\t0x%lx\n", LCA_GET_OVERRIDE(pmr_reg));
-        printk("\tInterrupt override is %s\n",
-              (pmr_reg & LCA_PMR_INTO) ? "on" : "off"); 
-        printk("\tDMA override is %s\n",
-              (pmr_reg & LCA_PMR_DMAO) ? "on" : "off"); 
-
-}
-
-int
-lca_get_clock(void)
-{
-        long    pmr_reg;
-
-        pmr_reg = LCA_READ_PMR;
-        return(LCA_GET_PRIMARY(pmr_reg));
-
-}
-
-void
-lca_clock_fiddle(int divisor)
-{
-        long    pmr_reg;
-
-        pmr_reg = LCA_READ_PMR;
-        LCA_SET_PRIMARY_CLOCK(pmr_reg, divisor);
-       /* lca_norm_clock = divisor; */
-        LCA_WRITE_PMR(pmr_reg);
-        mb();
-}
index e9348aec464990517a5e13f5f16fdbdfaef4eb9b..b22248044bf04549d933b5f07d1f60ea599afded 100644 (file)
@@ -355,7 +355,7 @@ marvel_init_io7(struct io7 *io7)
        }
 }
 
-void __init
+static void __init
 marvel_io7_present(gct6_node *node)
 {
        int pe;
index 98d5b6ff8a769632a12304bb165b1e9d06c96d45..3d72d90624f11d767d9583e60da7c4d9fbada4bd 100644 (file)
@@ -10,7 +10,7 @@
  * Code common to all T2 core logic chips.
  */
 
-#define __EXTERN_INLINE
+#define __EXTERN_INLINE inline
 #include <asm/io.h>
 #include <asm/core_t2.h>
 #undef __EXTERN_INLINE
index 3a804b67f9da45d82300c2a5d95348d2ac718ed9..8dd08c5e42706699cd599d39aa314728fb3c888f 100644 (file)
@@ -59,7 +59,7 @@ unsigned long wildfire_pca_mask;
 unsigned long wildfire_cpu_mask;
 unsigned long wildfire_mem_mask;
 
-void __init
+static void __init
 wildfire_init_hose(int qbbno, int hoseno)
 {
        struct pci_controller *hose;
@@ -137,7 +137,7 @@ wildfire_init_hose(int qbbno, int hoseno)
        wildfire_pci_tbi(hose, 0, 0); /* Flush TLB at the end. */
 }
 
-void __init
+static void __init
 wildfire_init_pca(int qbbno, int pcano)
 {
 
@@ -154,7 +154,7 @@ wildfire_init_pca(int qbbno, int pcano)
        wildfire_init_hose(qbbno, (pcano << 1) + 1);
 }
 
-void __init
+static void __init
 wildfire_init_qbb(int qbbno)
 {
        int pcano;
@@ -176,7 +176,7 @@ wildfire_init_qbb(int qbbno)
        }
 }
 
-void __init
+static void __init
 wildfire_hardware_probe(void)
 {
        unsigned long temp;
index eb51f93a70c8f129a1061398befdc44882759bfb..dd26062d75b3c5691d2ea546fa53a22f1c1b0eaa 100644 (file)
@@ -811,6 +811,7 @@ alpha_\name:
 fork_like fork
 fork_like vfork
 fork_like clone
+fork_like clone3
 
 .macro sigreturn_like name
        .align  4
index eda09778268f0199e7730090752aff17eb865dd4..c28035d6d1e65328501035cce52035fcfb6adda2 100644 (file)
@@ -647,6 +647,10 @@ void _memset_c_io(volatile void __iomem *to, unsigned long c, long count)
 
 EXPORT_SYMBOL(_memset_c_io);
 
+#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE)
+
+#include <asm/vga.h>
+
 /* A version of memcpy used by the vga console routines to move data around
    arbitrarily between screen and main memory.  */
 
@@ -681,6 +685,21 @@ scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
 
 EXPORT_SYMBOL(scr_memcpyw);
 
+void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
+{
+       if (d < s)
+               scr_memcpyw(d, s, count);
+       else {
+               count /= 2;
+               d += count;
+               s += count;
+               while (count--)
+                       scr_writew(scr_readw(--s), --d);
+       }
+}
+EXPORT_SYMBOL(scr_memmovew);
+#endif
+
 void __iomem *ioport_map(unsigned long port, unsigned int size)
 {
        return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
index 15f2effd6baf80d272988a123388cc7dd7754af6..c67047c5d83045032346fa60f7ca371e2713cd67 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <asm/io.h>
 #include <linux/uaccess.h>
+#include "irq_impl.h"
 
 volatile unsigned long irq_err_count;
 DEFINE_PER_CPU(unsigned long, irq_pmi_count);
index 1dcf0d9038fdeb88b715ff576357db68b44f92cd..29c6c477ac359536b36846584db669d1585e67cd 100644 (file)
@@ -98,10 +98,6 @@ init_i8259a_irqs(void)
 
 #if defined(CONFIG_ALPHA_GENERIC)
 # define IACK_SC       alpha_mv.iack_sc
-#elif defined(CONFIG_ALPHA_APECS)
-# define IACK_SC       APECS_IACK_SC
-#elif defined(CONFIG_ALPHA_LCA)
-# define IACK_SC       LCA_IACK_SC
 #elif defined(CONFIG_ALPHA_CIA)
 # define IACK_SC       CIA_IACK_SC
 #elif defined(CONFIG_ALPHA_PYXIS)
index c2ebcb39e58967be49ac6ad8bb7b8646156ce659..129ae36b8e6d433f258f5cfe00f8e8ebc8a374c5 100644 (file)
 
 #define DO_DEFAULT_RTC                 .rtc_port = 0x70
 
-#define DO_EV4_MMU                                                     \
-       .max_asn =                      EV4_MAX_ASN,                    \
-       .mv_switch_mm =                 ev4_switch_mm,                  \
-       .mv_activate_mm =               ev4_activate_mm,                \
-       .mv_flush_tlb_current =         ev4_flush_tlb_current,          \
-       .mv_flush_tlb_current_page =    ev4_flush_tlb_current_page
-
 #define DO_EV5_MMU                                                     \
-       .max_asn =                      EV5_MAX_ASN,                    \
-       .mv_switch_mm =                 ev5_switch_mm,                  \
-       .mv_activate_mm =               ev5_activate_mm,                \
-       .mv_flush_tlb_current =         ev5_flush_tlb_current,          \
-       .mv_flush_tlb_current_page =    ev5_flush_tlb_current_page
+       .max_asn =                      EV5_MAX_ASN                     \
 
 #define DO_EV6_MMU                                                     \
-       .max_asn =                      EV6_MAX_ASN,                    \
-       .mv_switch_mm =                 ev5_switch_mm,                  \
-       .mv_activate_mm =               ev5_activate_mm,                \
-       .mv_flush_tlb_current =         ev5_flush_tlb_current,          \
-       .mv_flush_tlb_current_page =    ev5_flush_tlb_current_page
+       .max_asn =                      EV6_MAX_ASN                     \
 
 #define DO_EV7_MMU                                                     \
-       .max_asn =                      EV6_MAX_ASN,                    \
-       .mv_switch_mm =                 ev5_switch_mm,                  \
-       .mv_activate_mm =               ev5_activate_mm,                \
-       .mv_flush_tlb_current =         ev5_flush_tlb_current,          \
-       .mv_flush_tlb_current_page =    ev5_flush_tlb_current_page
+       .max_asn =                      EV6_MAX_ASN                     \
 
 #define IO_LITE(UP,low)                                                        \
        .hae_register =         (unsigned long *) CAT(UP,_HAE_ADDRESS), \
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
deleted file mode 100644 (file)
index ae82061..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/pci-noop.c
- *
- * Stub PCI interfaces for Jensen-specific kernels.
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/memblock.h>
-#include <linux/gfp.h>
-#include <linux/capability.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/dma-mapping.h>
-#include <linux/scatterlist.h>
-#include <linux/syscalls.h>
-
-#include "proto.h"
-
-
-/*
- * The PCI controller list.
- */
-
-struct pci_controller *hose_head, **hose_tail = &hose_head;
-struct pci_controller *pci_isa_hose;
-
-
-struct pci_controller * __init
-alloc_pci_controller(void)
-{
-       struct pci_controller *hose;
-
-       hose = memblock_alloc(sizeof(*hose), SMP_CACHE_BYTES);
-       if (!hose)
-               panic("%s: Failed to allocate %zu bytes\n", __func__,
-                     sizeof(*hose));
-
-       *hose_tail = hose;
-       hose_tail = &hose->next;
-
-       return hose;
-}
-
-struct resource * __init
-alloc_resource(void)
-{
-       void *ptr = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
-
-       if (!ptr)
-               panic("%s: Failed to allocate %zu bytes\n", __func__,
-                     sizeof(struct resource));
-
-       return ptr;
-}
-
-SYSCALL_DEFINE3(pciconfig_iobase, long, which, unsigned long, bus,
-               unsigned long, dfn)
-{
-       struct pci_controller *hose;
-
-       /* from hose or from bus.devfn */
-       if (which & IOBASE_FROM_HOSE) {
-               for (hose = hose_head; hose; hose = hose->next)
-                       if (hose->index == bus)
-                               break;
-               if (!hose)
-                       return -ENODEV;
-       } else {
-               /* Special hook for ISA access.  */
-               if (bus == 0 && dfn == 0)
-                       hose = pci_isa_hose;
-               else
-                       return -ENODEV;
-       }
-
-       switch (which & ~IOBASE_FROM_HOSE) {
-       case IOBASE_HOSE:
-               return hose->index;
-       case IOBASE_SPARSE_MEM:
-               return hose->sparse_mem_base;
-       case IOBASE_DENSE_MEM:
-               return hose->dense_mem_base;
-       case IOBASE_SPARSE_IO:
-               return hose->sparse_io_base;
-       case IOBASE_DENSE_IO:
-               return hose->dense_io_base;
-       case IOBASE_ROOT_BUS:
-               return hose->bus->number;
-       }
-
-       return -EOPNOTSUPP;
-}
-
-SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
-               unsigned long, off, unsigned long, len, void __user *, buf)
-{
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       else
-               return -ENODEV;
-}
-
-SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
-               unsigned long, off, unsigned long, len, void __user *, buf)
-{
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       else
-               return -ENODEV;
-}
index 18043af45e2b9148c7c94ab7b352e7dc4d586fab..a16325ce21c40afc7349e97fabe95a8ea87b4b54 100644 (file)
@@ -143,9 +143,7 @@ struct pci_iommu_arena
        unsigned int align_entry;
 };
 
-#if defined(CONFIG_ALPHA_SRM) && \
-    (defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \
-     defined(CONFIG_ALPHA_AVANTI))
+#if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_CIA)
 # define NEED_SRM_SAVE_RESTORE
 #else
 # undef NEED_SRM_SAVE_RESTORE
index ccdb508c151612e3594af427a28bf97fdebf1c2b..1f0eb4f25c0ff5380b5aa01641c35eb7767c134e 100644 (file)
@@ -870,7 +870,7 @@ static void alpha_perf_event_irq_handler(unsigned long la_ptr,
 /*
  * Init call to initialise performance events at kernel startup.
  */
-int __init init_hw_perf_events(void)
+static int __init init_hw_perf_events(void)
 {
        pr_info("Performance events: ");
 
index 2c89c1c557129bc11ef9f2c02a58726861d6aff4..a8bc3ead776ba0375d2e46e143184c54d8b0e4ee 100644 (file)
@@ -15,13 +15,7 @@ struct pt_regs;
 struct task_struct;
 struct pci_dev;
 struct pci_controller;
-
-/* core_apecs.c */
-extern struct pci_ops apecs_pci_ops;
-extern void apecs_init_arch(void);
-extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
-extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
+struct pci_bus;
 
 /* core_cia.c */
 extern struct pci_ops cia_pci_ops;
@@ -38,12 +32,6 @@ extern int irongate_pci_clr_err(void);
 extern void irongate_init_arch(void);
 #define irongate_pci_tbi ((void *)0)
 
-/* core_lca.c */
-extern struct pci_ops lca_pci_ops;
-extern void lca_init_arch(void);
-extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
-extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
-
 /* core_marvel.c */
 extern struct pci_ops marvel_pci_ops;
 extern void marvel_init_arch(void);
@@ -114,6 +102,9 @@ extern int boot_cpuid;
 #ifdef CONFIG_VERBOSE_MCHECK
 extern unsigned long alpha_verbose_mcheck;
 #endif
+#ifdef CONFIG_BLK_DEV_INITRD
+extern void * __init move_initrd(unsigned long);
+#endif
 extern struct screen_info vgacon_screen_info;
 
 /* srmcons.c */
@@ -128,6 +119,7 @@ extern void unregister_srm_console(void);
 /* smp.c */
 extern void setup_smp(void);
 extern void handle_ipi(struct pt_regs *);
+extern void __init smp_callin(void);
 
 /* bios32.c */
 /* extern void reset_for_srm(void); */
@@ -139,13 +131,13 @@ extern void common_init_rtc(void);
 extern unsigned long est_cycle_freq;
 
 /* smc37c93x.c */
-extern void SMC93x_Init(void);
+extern int __init SMC93x_Init(void);
 
 /* smc37c669.c */
-extern void SMC669_Init(int);
+extern void __init SMC669_Init(int);
 
 /* es1888.c */
-extern void es1888_init(void);
+extern void __init es1888_init(void);
 
 /* ../lib/fpreg.c */
 extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
@@ -166,19 +158,37 @@ extern void entSys(void);
 extern void entUna(void);
 extern void entDbg(void);
 
+/* pci.c */
+extern void pcibios_claim_one_bus(struct pci_bus *);
+
 /* ptrace.c */
 extern int ptrace_set_bpt (struct task_struct *child);
 extern int ptrace_cancel_bpt (struct task_struct *child);
+extern void syscall_trace_leave(void);
+extern unsigned long syscall_trace_enter(void);
+
+/* signal.c */
+struct sigcontext;
+extern void do_sigreturn(struct sigcontext __user *);
+struct rt_sigframe;
+extern void do_rt_sigreturn(struct rt_sigframe __user *);
+extern void do_work_pending(struct pt_regs *, unsigned long, unsigned long, unsigned long);
 
 /* traps.c */
 extern void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15);
 extern void die_if_kernel(char *, struct pt_regs *, long, unsigned long *);
+extern void do_entInt(unsigned long, unsigned long, unsigned long, struct pt_regs *);
+extern void do_entArith(unsigned long, unsigned long, struct pt_regs *);
+extern void do_entIF(unsigned long, struct pt_regs *);
+extern void do_entDbg(struct pt_regs *);
+struct allregs;
+extern void do_entUna(void *, unsigned long, unsigned long, struct allregs *);
+extern void do_entUnaUser(void __user *, unsigned long, unsigned long, struct pt_regs *);
 
 /* sys_titan.c */
 extern void titan_dispatch_irqs(u64);
 
 /* ../mm/init.c */
-extern void switch_to_system_map(void);
 extern void srm_paging_stop(void);
 
 static inline int
index 0738f9396f957a1ca29acacc0a3765012e928ecf..bebdffafaee82e17177d0ba60a4bb52c952da024 100644 (file)
@@ -171,35 +171,22 @@ EXPORT_SYMBOL(__direct_map_size);
        asm(".weak "#X)
 
 WEAK(alcor_mv);
-WEAK(alphabook1_mv);
-WEAK(avanti_mv);
-WEAK(cabriolet_mv);
 WEAK(clipper_mv);
 WEAK(dp264_mv);
 WEAK(eb164_mv);
-WEAK(eb64p_mv);
-WEAK(eb66_mv);
-WEAK(eb66p_mv);
 WEAK(eiger_mv);
-WEAK(jensen_mv);
 WEAK(lx164_mv);
-WEAK(lynx_mv);
 WEAK(marvel_ev7_mv);
 WEAK(miata_mv);
-WEAK(mikasa_mv);
 WEAK(mikasa_primo_mv);
 WEAK(monet_mv);
 WEAK(nautilus_mv);
-WEAK(noname_mv);
-WEAK(noritake_mv);
 WEAK(noritake_primo_mv);
-WEAK(p2k_mv);
 WEAK(pc164_mv);
 WEAK(privateer_mv);
 WEAK(rawhide_mv);
 WEAK(ruffian_mv);
 WEAK(rx164_mv);
-WEAK(sable_mv);
 WEAK(sable_gamma_mv);
 WEAK(shark_mv);
 WEAK(sx164_mv);
@@ -207,7 +194,6 @@ WEAK(takara_mv);
 WEAK(titan_mv);
 WEAK(webbrick_mv);
 WEAK(wildfire_mv);
-WEAK(xl_mv);
 WEAK(xlt_mv);
 
 #undef WEAK
@@ -224,7 +210,7 @@ static void __init
 reserve_std_resources(void)
 {
        static struct resource standard_io_resources[] = {
-               { .name = "rtc", .start = -1, .end = -1 },
+               { .name = "rtc", .start = 0x70, .end =  0x7f},
                { .name = "dma1", .start = 0x00, .end = 0x1f },
                { .name = "pic1", .start = 0x20, .end = 0x3f },
                { .name = "timer", .start = 0x40, .end = 0x5f },
@@ -246,10 +232,6 @@ reserve_std_resources(void)
                        }
        }
 
-       /* Fix up for the Jensen's queer RTC placement.  */
-       standard_io_resources[0].start = RTC_PORT(0);
-       standard_io_resources[0].end = RTC_PORT(0) + 0x0f;
-
        for (i = 0; i < ARRAY_SIZE(standard_io_resources); ++i)
                request_resource(io, standard_io_resources+i);
 }
@@ -486,14 +468,7 @@ setup_arch(char **cmdline_p)
        /* 
         * Locate the command line.
         */
-       /* Hack for Jensen... since we're restricted to 8 or 16 chars for
-          boot flags depending on the boot mode, we need some shorthand.
-          This should do for installation.  */
-       if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
-               strscpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof(command_line));
-       } else {
-               strscpy(command_line, COMMAND_LINE, sizeof(command_line));
-       }
+       strscpy(command_line, COMMAND_LINE, sizeof(command_line));
        strcpy(boot_command_line, command_line);
        *cmdline_p = command_line;
 
@@ -706,12 +681,6 @@ static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
 static char alcor_names[][16] = {"Alcor", "Maverick", "Bret"};
 static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
 
-static char eb64p_names[][16] = {"EB64+", "Cabriolet", "AlphaPCI64"};
-static int eb64p_indices[] = {0,0,1,2};
-
-static char eb66_names[][8] = {"EB66", "EB66+"};
-static int eb66_indices[] = {0,0,1};
-
 static char marvel_names[][16] = {
        "Marvel/EV7"
 };
@@ -745,26 +714,26 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
                NULL,           /* Ruby */
                NULL,           /* Flamingo */
                NULL,           /* Mannequin */
-               &jensen_mv,
+               NULL,           /* Jensens */
                NULL,           /* Pelican */
                NULL,           /* Morgan */
                NULL,           /* Sable -- see below.  */
                NULL,           /* Medulla */
-               &noname_mv,
+               NULL,           /* Noname */
                NULL,           /* Turbolaser */
-               &avanti_mv,
+               NULL,           /* Avanti */
                NULL,           /* Mustang */
                NULL,           /* Alcor, Bret, Maverick. HWRPB inaccurate? */
                NULL,           /* Tradewind */
                NULL,           /* Mikasa -- see below.  */
                NULL,           /* EB64 */
-               NULL,           /* EB66 -- see variation.  */
-               NULL,           /* EB64+ -- see variation.  */
-               &alphabook1_mv,
+               NULL,           /* EB66 */
+               NULL,           /* EB64+ */
+               NULL,           /* Alphabook1 */
                &rawhide_mv,
                NULL,           /* K2 */
-               &lynx_mv,       /* Lynx */
-               &xl_mv,
+               NULL,           /* Lynx */
+               NULL,           /* XL */
                NULL,           /* EB164 -- see variation.  */
                NULL,           /* Noritake -- see below.  */
                NULL,           /* Cortex */
@@ -803,19 +772,6 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
                &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv, &rx164_mv
        };
 
-       static struct alpha_machine_vector *eb64p_vecs[] __initdata =
-       {
-               &eb64p_mv,
-               &cabriolet_mv,
-               &cabriolet_mv           /* AlphaPCI64 */
-       };
-
-       static struct alpha_machine_vector *eb66_vecs[] __initdata =
-       {
-               &eb66_mv,
-               &eb66p_mv
-       };
-
        static struct alpha_machine_vector *marvel_vecs[] __initdata =
        {
                &marvel_ev7_mv,
@@ -883,14 +839,6 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
                        if (vec == &eb164_mv && cpu == EV56_CPU)
                                vec = &pc164_mv;
                        break;
-               case ST_DEC_EB64P:
-                       if (member < ARRAY_SIZE(eb64p_indices))
-                               vec = eb64p_vecs[eb64p_indices[member]];
-                       break;
-               case ST_DEC_EB66:
-                       if (member < ARRAY_SIZE(eb66_indices))
-                               vec = eb66_vecs[eb66_indices[member]];
-                       break;
                case ST_DEC_MARVEL:
                        if (member < ARRAY_SIZE(marvel_indices))
                                vec = marvel_vecs[marvel_indices[member]];
@@ -905,22 +853,13 @@ get_sysvec(unsigned long type, unsigned long variation, unsigned long cpu)
                                vec = tsunami_vecs[tsunami_indices[member]];
                        break;
                case ST_DEC_1000:
-                       if (cpu == EV5_CPU || cpu == EV56_CPU)
-                               vec = &mikasa_primo_mv;
-                       else
-                               vec = &mikasa_mv;
+                       vec = &mikasa_primo_mv;
                        break;
                case ST_DEC_NORITAKE:
-                       if (cpu == EV5_CPU || cpu == EV56_CPU)
-                               vec = &noritake_primo_mv;
-                       else
-                               vec = &noritake_mv;
+                       vec = &noritake_primo_mv;
                        break;
                case ST_DEC_2100_A500:
-                       if (cpu == EV5_CPU || cpu == EV56_CPU)
-                               vec = &sable_gamma_mv;
-                       else
-                               vec = &sable_mv;
+                       vec = &sable_gamma_mv;
                        break;
                }
        }
@@ -933,41 +872,27 @@ get_sysvec_byname(const char *name)
        static struct alpha_machine_vector *all_vecs[] __initdata =
        {
                &alcor_mv,
-               &alphabook1_mv,
-               &avanti_mv,
-               &cabriolet_mv,
                &clipper_mv,
                &dp264_mv,
                &eb164_mv,
-               &eb64p_mv,
-               &eb66_mv,
-               &eb66p_mv,
                &eiger_mv,
-               &jensen_mv,
                &lx164_mv,
-               &lynx_mv,
                &miata_mv,
-               &mikasa_mv,
                &mikasa_primo_mv,
                &monet_mv,
                &nautilus_mv,
-               &noname_mv,
-               &noritake_mv,
                &noritake_primo_mv,
-               &p2k_mv,
                &pc164_mv,
                &privateer_mv,
                &rawhide_mv,
                &ruffian_mv,
                &rx164_mv,
-               &sable_mv,
                &sable_gamma_mv,
                &shark_mv,
                &sx164_mv,
                &takara_mv,
                &webbrick_mv,
                &wildfire_mv,
-               &xl_mv,
                &xlt_mv
        };
 
@@ -1029,14 +954,6 @@ get_sysnames(unsigned long type, unsigned long variation, unsigned long cpu,
                if (member < ARRAY_SIZE(alcor_indices))
                        *variation_name = alcor_names[alcor_indices[member]];
                break;
-       case ST_DEC_EB64P:
-               if (member < ARRAY_SIZE(eb64p_indices))
-                       *variation_name = eb64p_names[eb64p_indices[member]];
-               break;
-       case ST_DEC_EB66:
-               if (member < ARRAY_SIZE(eb66_indices))
-                       *variation_name = eb66_names[eb66_indices[member]];
-               break;
        case ST_DEC_MARVEL:
                if (member < ARRAY_SIZE(marvel_indices))
                        *variation_name = marvel_names[marvel_indices[member]];
index bbbd34586de01e1f11fe4ba1d6f21f1f8b0a2119..a5a6ed97a6ce0d6c1cb8936655cd15c5f3d326af 100644 (file)
@@ -11,6 +11,8 @@
 #include <asm/hwrpb.h>
 #include <asm/io.h>
 
+#include "proto.h"
+
 #if 0
 # define DBG_DEVS(args)         printk args
 #else
@@ -2430,13 +2432,15 @@ int __init smcc669_write( struct FILE *fp, int size, int number, unsigned char *
 }
 #endif
 
-void __init
+#if SMC_DEBUG
+static void __init
 SMC37c669_dump_registers(void)
 {
   int i;
   for (i = 0; i <= 0x29; i++)
     printk("-- CR%02x : %02x\n", i, SMC37c669_read_config(i));
 }
+#endif
 /*+
  * ============================================================================
  * = SMC_init - SMC37c669 Super I/O controller initialization                 =
index 71cd7aca38ce2464be5a0e2dad8a21a57a800ee7..8028273f0d161f642fec8fd2e688fa044b42009c 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/hwrpb.h>
 #include <asm/io.h>
 
+#include "proto.h"
+
 #define SMC_DEBUG 0
 
 #if SMC_DEBUG
index 8e9dd63b220c68f1f9cbb4cfa470192900ea10f2..ed06367ece5749b29a07661a910a1f0a15022ab6 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 
 #include "proto.h"
 #include "irq_impl.h"
index feaf89f6936bcd1a82b9fe9ae12ef06daa8fcb64..3e61073f4b3018123ec73e265546fc689e78e3db 100644 (file)
@@ -21,6 +21,8 @@
 #include <asm/console.h>
 #include <linux/uaccess.h>
 
+#include "proto.h"
+
 
 static DEFINE_SPINLOCK(srmcons_callback_lock);
 static int srm_is_registered_console = 0;
index 47459b73cdb7e2ee0afd551cfd79ca3b80f5a265..54e75d4fdbe3eb005c03408eb9a9d580526dd618 100644 (file)
@@ -6,8 +6,7 @@
  *     Copyright (C) 1996 Jay A Estabrook
  *     Copyright (C) 1998, 1999, 2000 Richard Henderson
  *
- * Code supporting the Cabriolet (AlphaPC64), EB66+, and EB164,
- * PC164 and LX164.
+ * Code supporting the PC164 and LX164.
  */
 
 #include <linux/kernel.h>
@@ -23,9 +22,7 @@
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/io.h>
-#include <asm/core_apecs.h>
 #include <asm/core_cia.h>
-#include <asm/core_lca.h>
 #include <asm/tlbflush.h>
 
 #include "proto.h"
@@ -232,13 +229,6 @@ cabriolet_enable_ide(void)
        }
 }
 
-static inline void __init
-cabriolet_init_pci(void)
-{
-       common_init_pci();
-       cabriolet_enable_ide();
-}
-
 static inline void __init
 cia_cab_init_pci(void)
 {
@@ -317,81 +307,6 @@ alphapc164_init_pci(void)
  * The System Vector
  */
 
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
-struct alpha_machine_vector cabriolet_mv __initmv = {
-       .vector_name            = "Cabriolet",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 35,
-       .device_interrupt       = cabriolet_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = cabriolet_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = cabriolet_init_pci,
-       .pci_map_irq            = cabriolet_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-#ifndef CONFIG_ALPHA_EB64P
-ALIAS_MV(cabriolet)
-#endif
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
-struct alpha_machine_vector eb164_mv __initmv = {
-       .vector_name            = "EB164",
-       DO_EV5_MMU,
-       DO_DEFAULT_RTC,
-       DO_CIA_IO,
-       .machine_check          = cia_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = CIA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 35,
-       .device_interrupt       = cabriolet_device_interrupt,
-
-       .init_arch              = cia_init_arch,
-       .init_irq               = cabriolet_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = cia_cab_init_pci,
-       .kill_arch              = cia_kill_arch,
-       .pci_map_irq            = cabriolet_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-ALIAS_MV(eb164)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66P)
-struct alpha_machine_vector eb66p_mv __initmv = {
-       .vector_name            = "EB66+",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_LCA_IO,
-       .machine_check          = lca_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 35,
-       .device_interrupt       = cabriolet_device_interrupt,
-
-       .init_arch              = lca_init_arch,
-       .init_irq               = cabriolet_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = cabriolet_init_pci,
-       .pci_map_irq            = eb66p_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-ALIAS_MV(eb66p)
-#endif
-
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LX164)
 struct alpha_machine_vector lx164_mv __initmv = {
        .vector_name            = "LX164",
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
deleted file mode 100644 (file)
index 3c43fd3..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/sys_eb64p.c
- *
- *     Copyright (C) 1995 David A Rusling
- *     Copyright (C) 1996 Jay A Estabrook
- *     Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code supporting the EB64+ and EB66.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-
-#include <asm/ptrace.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#include <asm/core_lca.h>
-#include <asm/hwrpb.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-
-
-/* Note mask bit is true for DISABLED irqs.  */
-static unsigned int cached_irq_mask = -1;
-
-static inline void
-eb64p_update_irq_hw(unsigned int irq, unsigned long mask)
-{
-       outb(mask >> (irq >= 24 ? 24 : 16), (irq >= 24 ? 0x27 : 0x26));
-}
-
-static inline void
-eb64p_enable_irq(struct irq_data *d)
-{
-       eb64p_update_irq_hw(d->irq, cached_irq_mask &= ~(1 << d->irq));
-}
-
-static void
-eb64p_disable_irq(struct irq_data *d)
-{
-       eb64p_update_irq_hw(d->irq, cached_irq_mask |= 1 << d->irq);
-}
-
-static struct irq_chip eb64p_irq_type = {
-       .name           = "EB64P",
-       .irq_unmask     = eb64p_enable_irq,
-       .irq_mask       = eb64p_disable_irq,
-       .irq_mask_ack   = eb64p_disable_irq,
-};
-
-static void 
-eb64p_device_interrupt(unsigned long vector)
-{
-       unsigned long pld;
-       unsigned int i;
-
-       /* Read the interrupt summary registers */
-       pld = inb(0x26) | (inb(0x27) << 8);
-
-       /*
-        * Now, for every possible bit set, work through
-        * them and call the appropriate interrupt handler.
-        */
-       while (pld) {
-               i = ffz(~pld);
-               pld &= pld - 1; /* clear least bit set */
-
-               if (i == 5) {
-                       isa_device_interrupt(vector);
-               } else {
-                       handle_irq(16 + i);
-               }
-       }
-}
-
-static void __init
-eb64p_init_irq(void)
-{
-       long i;
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
-       /*
-        * CABRIO SRM may not set variation correctly, so here we test
-        * the high word of the interrupt summary register for the RAZ
-        * bits, and hope that a true EB64+ would read all ones...
-        */
-       if (inw(0x806) != 0xffff) {
-               extern struct alpha_machine_vector cabriolet_mv;
-
-               printk("Detected Cabriolet: correcting HWRPB.\n");
-
-               hwrpb->sys_variation |= 2L << 10;
-               hwrpb_update_checksum(hwrpb);
-
-               alpha_mv = cabriolet_mv;
-               alpha_mv.init_irq();
-               return;
-       }
-#endif /* GENERIC */
-
-       outb(0xff, 0x26);
-       outb(0xff, 0x27);
-
-       init_i8259a_irqs();
-
-       for (i = 16; i < 32; ++i) {
-               irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
-               irq_set_status_flags(i, IRQ_LEVEL);
-       }
-
-       common_init_isa_dma();
-       if (request_irq(16 + 5, no_action, 0, "isa-cascade", NULL))
-               pr_err("Failed to register isa-cascade interrupt\n");
-}
-
-/*
- * PCI Fixup configuration.
- *
- * There are two 8 bit external summary registers as follows:
- *
- * Summary @ 0x26:
- * Bit      Meaning
- * 0        Interrupt Line A from slot 0
- * 1        Interrupt Line A from slot 1
- * 2        Interrupt Line B from slot 0
- * 3        Interrupt Line B from slot 1
- * 4        Interrupt Line C from slot 0
- * 5        Interrupt line from the two ISA PICs
- * 6        Tulip
- * 7        NCR SCSI
- *
- * Summary @ 0x27
- * Bit      Meaning
- * 0        Interrupt Line C from slot 1
- * 1        Interrupt Line D from slot 0
- * 2        Interrupt Line D from slot 1
- * 3        RAZ
- * 4        RAZ
- * 5        RAZ
- * 6        RAZ
- * 7        RAZ
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  5       NCR SCSI controller
- *  6       PCI on board slot 0
- *  7       PCI on board slot 1
- *  8       Intel SIO PCI-ISA bridge chip
- *  9       Tulip - DECchip 21040 Ethernet controller
- *   
- *
- * This two layered interrupt approach means that we allocate IRQ 16 and 
- * above for PCI interrupts.  The IRQ relates to which bit the interrupt
- * comes in on.  This makes interrupt processing much easier.
- */
-
-static int
-eb64p_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       static char irq_tab[5][5] = {
-               /*INT  INTA  INTB  INTC   INTD */
-               {16+7, 16+7, 16+7, 16+7,  16+7},  /* IdSel 5,  slot ?, ?? */
-               {16+0, 16+0, 16+2, 16+4,  16+9},  /* IdSel 6,  slot ?, ?? */
-               {16+1, 16+1, 16+3, 16+8, 16+10},  /* IdSel 7,  slot ?, ?? */
-               {  -1,   -1,   -1,   -1,    -1},  /* IdSel 8,  SIO */
-               {16+6, 16+6, 16+6, 16+6,  16+6},  /* IdSel 9,  TULIP */
-       };
-       const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
-       return COMMON_TABLE_LOOKUP;
-}
-
-
-/*
- * The System Vector
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB64P)
-struct alpha_machine_vector eb64p_mv __initmv = {
-       .vector_name            = "EB64+",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 32,
-       .device_interrupt       = eb64p_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = eb64p_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = common_init_pci,
-       .kill_arch              = NULL,
-       .pci_map_irq            = eb64p_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-ALIAS_MV(eb64p)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB66)
-struct alpha_machine_vector eb66_mv __initmv = {
-       .vector_name            = "EB66",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_LCA_IO,
-       .machine_check          = lca_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 32,
-       .device_interrupt       = eb64p_device_interrupt,
-
-       .init_arch              = lca_init_arch,
-       .init_irq               = eb64p_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = common_init_pci,
-       .pci_map_irq            = eb64p_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-ALIAS_MV(eb66)
-#endif
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
deleted file mode 100644 (file)
index 5c9c884..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/sys_jensen.c
- *
- *     Copyright (C) 1995 Linus Torvalds
- *     Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code supporting the Jensen.
- */
-#define __EXTERN_INLINE
-#include <asm/io.h>
-#include <asm/jensen.h>
-#undef  __EXTERN_INLINE
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-
-#include <asm/ptrace.h>
-
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-
-
-/*
- * Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
- * 0x9X0 for the local motherboard interrupts.
- *
- * Note especially that those local interrupts CANNOT be masked,
- * which causes much of the pain below...
- *
- *     0x660 - NMI
- *
- *     0x800 - IRQ0  interval timer (not used, as we use the RTC timer)
- *     0x810 - IRQ1  line printer (duh..)
- *     0x860 - IRQ6  floppy disk
- *
- *     0x900 - COM1
- *     0x920 - COM2
- *     0x980 - keyboard
- *     0x990 - mouse
- *
- * PCI-based systems are more sane: they don't have the local
- * interrupts at all, and have only normal PCI interrupts from
- * devices.  Happily it's easy enough to do a sane mapping from the
- * Jensen.
- * 
- * Note that this means that we may have to do a hardware
- * "local_op" to a different interrupt than we report to the rest of the
- * world.
- */
-
-static void
-jensen_local_enable(struct irq_data *d)
-{
-       /* the parport is really hw IRQ 1, silly Jensen.  */
-       if (d->irq == 7)
-               i8259a_enable_irq(d);
-}
-
-static void
-jensen_local_disable(struct irq_data *d)
-{
-       /* the parport is really hw IRQ 1, silly Jensen.  */
-       if (d->irq == 7)
-               i8259a_disable_irq(d);
-}
-
-static void
-jensen_local_mask_ack(struct irq_data *d)
-{
-       /* the parport is really hw IRQ 1, silly Jensen.  */
-       if (d->irq == 7)
-               i8259a_mask_and_ack_irq(d);
-}
-
-static struct irq_chip jensen_local_irq_type = {
-       .name           = "LOCAL",
-       .irq_unmask     = jensen_local_enable,
-       .irq_mask       = jensen_local_disable,
-       .irq_mask_ack   = jensen_local_mask_ack,
-};
-
-static void 
-jensen_device_interrupt(unsigned long vector)
-{
-       int irq;
-
-       switch (vector) {
-       case 0x660:
-               printk("Whee.. NMI received. Probable hardware error\n");
-               printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
-               return;
-
-       /* local device interrupts: */
-       case 0x900: irq = 4; break;             /* com1 -> irq 4 */
-       case 0x920: irq = 3; break;             /* com2 -> irq 3 */
-       case 0x980: irq = 1; break;             /* kbd -> irq 1 */
-       case 0x990: irq = 9; break;             /* mouse -> irq 9 */
-
-       default:
-               if (vector > 0x900) {
-                       printk("Unknown local interrupt %lx\n", vector);
-                       return;
-               }
-
-               irq = (vector - 0x800) >> 4;
-               if (irq == 1)
-                       irq = 7;
-               break;
-       }
-
-       /* If there is no handler yet... */
-       if (!irq_has_action(irq)) {
-           /* If it is a local interrupt that cannot be masked... */
-           if (vector >= 0x900)
-           {
-               /* Clear keyboard/mouse state */
-               inb(0x64);
-               inb(0x60);
-               /* Reset serial ports */
-               inb(0x3fa);
-               inb(0x2fa);
-               outb(0x0c, 0x3fc);
-               outb(0x0c, 0x2fc);
-               /* Clear NMI */
-               outb(0,0x61);
-               outb(0,0x461);
-           }
-       }
-
-#if 0
-        /* A useful bit of code to find out if an interrupt is going wild.  */
-        {
-          static unsigned int last_msg = 0, last_cc = 0;
-          static int last_irq = -1, count = 0;
-          unsigned int cc;
-
-          __asm __volatile("rpcc %0" : "=r"(cc));
-          ++count;
-#define JENSEN_CYCLES_PER_SEC  (150000000)
-          if (cc - last_msg > ((JENSEN_CYCLES_PER_SEC) * 3) ||
-             irq != last_irq) {
-                printk(KERN_CRIT " irq %d count %d cc %u @ %lx\n",
-                       irq, count, cc-last_cc, get_irq_regs()->pc);
-                count = 0;
-                last_msg = cc;
-                last_irq = irq;
-          }
-          last_cc = cc;
-        }
-#endif
-
-       handle_irq(irq);
-}
-
-static void __init
-jensen_init_irq(void)
-{
-       init_i8259a_irqs();
-
-       irq_set_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq);
-       irq_set_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq);
-       irq_set_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq);
-       irq_set_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq);
-       irq_set_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);
-
-       common_init_isa_dma();
-}
-
-static void __init
-jensen_init_arch(void)
-{
-       struct pci_controller *hose;
-#ifdef CONFIG_PCI
-       static struct pci_dev fake_isa_bridge = { .dma_mask = 0xffffffffUL, };
-
-       isa_bridge = &fake_isa_bridge;
-#endif
-
-       /* Create a hose so that we can report i/o base addresses to
-          userland.  */
-
-       pci_isa_hose = hose = alloc_pci_controller();
-       hose->io_space = &ioport_resource;
-       hose->mem_space = &iomem_resource;
-       hose->index = 0;
-
-       hose->sparse_mem_base = EISA_MEM - IDENT_ADDR;
-       hose->dense_mem_base = 0;
-       hose->sparse_io_base = EISA_IO - IDENT_ADDR;
-       hose->dense_io_base = 0;
-
-       hose->sg_isa = hose->sg_pci = NULL;
-       __direct_map_base = 0;
-       __direct_map_size = 0xffffffff;
-}
-
-static void
-jensen_machine_check(unsigned long vector, unsigned long la)
-{
-       printk(KERN_CRIT "Machine check\n");
-}
-
-/*
- * The System Vector
- */
-
-struct alpha_machine_vector jensen_mv __initmv = {
-       .vector_name            = "Jensen",
-       DO_EV4_MMU,
-       IO_LITE(JENSEN,jensen),
-       .machine_check          = jensen_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .rtc_port               = 0x170,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = jensen_device_interrupt,
-
-       .init_arch              = jensen_init_arch,
-       .init_irq               = jensen_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = NULL,
-       .kill_arch              = NULL,
-};
-ALIAS_MV(jensen)
index 7690dfd57cb6bc5aaf8c3bcc92e8a033c32b817a..55780239823189adb78107c5e4d558655b4d2d3f 100644 (file)
@@ -23,7 +23,6 @@
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/io.h>
-#include <asm/core_apecs.h>
 #include <asm/core_cia.h>
 #include <asm/tlbflush.h>
 
@@ -164,64 +163,9 @@ mikasa_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 }
 
 
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-static void
-mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-#define MCHK_NO_DEVSEL 0x205U
-#define MCHK_NO_TABT 0x204U
-
-       struct el_common *mchk_header;
-       unsigned int code;
-
-       mchk_header = (struct el_common *)la_ptr;
-
-       /* Clear the error before any reporting.  */
-       mb();
-       mb(); /* magic */
-       draina();
-       apecs_pci_clr_err();
-       wrmces(0x7);
-       mb();
-
-       code = mchk_header->code;
-       process_mcheck_info(vector, la_ptr, "MIKASA APECS",
-                           (mcheck_expected(0)
-                            && (code == MCHK_NO_DEVSEL
-                                || code == MCHK_NO_TABT)));
-}
-#endif
-
-
 /*
  * The System Vector
  */
-
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-struct alpha_machine_vector mikasa_mv __initmv = {
-       .vector_name            = "Mikasa",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = mikasa_apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 32,
-       .device_interrupt       = mikasa_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = mikasa_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = common_init_pci,
-       .pci_map_irq            = mikasa_map_irq,
-       .pci_swizzle            = common_swizzle,
-};
-ALIAS_MV(mikasa)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
 struct alpha_machine_vector mikasa_primo_mv __initmv = {
        .vector_name            = "Mikasa-Primo",
        DO_EV5_MMU,
@@ -244,4 +188,3 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
        .pci_swizzle            = common_swizzle,
 };
 ALIAS_MV(mikasa_primo)
-#endif
index 96fd6ff3fe81a0b59bb9154498795e53f81b398f..13b79960b4b90fe475c9fb68ba2a3436439016d1 100644 (file)
@@ -78,7 +78,7 @@ nautilus_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        return irq;
 }
 
-void
+static void
 nautilus_kill_arch(int mode)
 {
        struct pci_bus *bus = pci_isa_hose->bus;
@@ -127,7 +127,7 @@ naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
 /* Machine checks can come from two sources - those on the CPU and those
    in the system.  They are analysed separately but all starts here.  */
 
-void
+static void
 nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
 {
        char *mchk_class;
@@ -184,8 +184,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
        mb();
 }
 
-extern void pcibios_claim_one_bus(struct pci_bus *);
-
 static struct resource irongate_mem = {
        .name   = "Irongate PCI MEM",
        .flags  = IORESOURCE_MEM,
@@ -197,7 +195,7 @@ static struct resource busn_resource = {
        .flags  = IORESOURCE_BUS,
 };
 
-void __init
+static void __init
 nautilus_init_pci(void)
 {
        struct pci_controller *hose = hose_head;
index 47f3ce4f719adabeef155daaa8d0e8a7e6cd1d0a..eed3f16561c0f546519b052764b60e62cef1aeca 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/io.h>
-#include <asm/core_apecs.h>
 #include <asm/core_cia.h>
 #include <asm/tlbflush.h>
 
@@ -253,64 +252,6 @@ noritake_swizzle(struct pci_dev *dev, u8 *pinp)
        return slot;
 }
 
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-static void
-noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr)
-{
-#define MCHK_NO_DEVSEL 0x205U
-#define MCHK_NO_TABT 0x204U
-
-        struct el_common *mchk_header;
-        unsigned int code;
-
-        mchk_header = (struct el_common *)la_ptr;
-
-        /* Clear the error before any reporting.  */
-        mb();
-        mb(); /* magic */
-        draina();
-        apecs_pci_clr_err();
-        wrmces(0x7);
-        mb();
-
-        code = mchk_header->code;
-        process_mcheck_info(vector, la_ptr, "NORITAKE APECS",
-                            (mcheck_expected(0)
-                             && (code == MCHK_NO_DEVSEL
-                                 || code == MCHK_NO_TABT)));
-}
-#endif
-
-
-/*
- * The System Vectors
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
-struct alpha_machine_vector noritake_mv __initmv = {
-       .vector_name            = "Noritake",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = noritake_apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = EISA_DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 48,
-       .device_interrupt       = noritake_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = noritake_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = common_init_pci,
-       .pci_map_irq            = noritake_map_irq,
-       .pci_swizzle            = noritake_swizzle,
-};
-ALIAS_MV(noritake)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_PRIMO)
 struct alpha_machine_vector noritake_primo_mv __initmv = {
        .vector_name            = "Noritake-Primo",
        DO_EV5_MMU,
@@ -333,4 +274,3 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
        .pci_swizzle            = noritake_swizzle,
 };
 ALIAS_MV(noritake_primo)
-#endif
index 930005b2f630dd531d6d32d28101e9ae9bd4e9e4..49f5c75134ec6701cdce6328e69561cf19d292ce 100644 (file)
@@ -212,232 +212,6 @@ sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 }
 #endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */
 
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
-
-/***********************************************************************/
-/* LYNX hardware specifics
- */
-/*
- *   For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC.
- *
- * Bit      Meaning               Kernel IRQ
- *------------------------------------------
- * 0        
- * 1        
- * 2        
- * 3        mouse                      12
- * 4        
- * 5        
- * 6        keyboard                   1
- * 7        floppy                     6
- * 8        COM2                       3
- * 9        parallel port              7
- *10        EISA irq 3                 -
- *11        EISA irq 4                 -
- *12        EISA irq 5                 5
- *13        EISA irq 6                 -
- *14        EISA irq 7                 -
- *15        COM1                       4
- *16        EISA irq 9                 9
- *17        EISA irq 10                        10
- *18        EISA irq 11                        11
- *19        EISA irq 12                        -
- *20        
- *21        EISA irq 14                        14
- *22        EISA irq 15                        15
- *23        IIC                                -
- *24        VGA (builtin)               -
- *25
- *26
- *27
- *28        NCR810 (builtin)           28
- *29
- *30
- *31
- *32        PCI 0 slot 4 A primary bus  32
- *33        PCI 0 slot 4 B primary bus  33
- *34        PCI 0 slot 4 C primary bus  34
- *35        PCI 0 slot 4 D primary bus
- *36        PCI 0 slot 5 A primary bus
- *37        PCI 0 slot 5 B primary bus
- *38        PCI 0 slot 5 C primary bus
- *39        PCI 0 slot 5 D primary bus
- *40        PCI 0 slot 6 A primary bus
- *41        PCI 0 slot 6 B primary bus
- *42        PCI 0 slot 6 C primary bus
- *43        PCI 0 slot 6 D primary bus
- *44        PCI 0 slot 7 A primary bus
- *45        PCI 0 slot 7 B primary bus
- *46        PCI 0 slot 7 C primary bus
- *47        PCI 0 slot 7 D primary bus
- *48        PCI 0 slot 0 A secondary bus
- *49        PCI 0 slot 0 B secondary bus
- *50        PCI 0 slot 0 C secondary bus
- *51        PCI 0 slot 0 D secondary bus
- *52        PCI 0 slot 1 A secondary bus
- *53        PCI 0 slot 1 B secondary bus
- *54        PCI 0 slot 1 C secondary bus
- *55        PCI 0 slot 1 D secondary bus
- *56        PCI 0 slot 2 A secondary bus
- *57        PCI 0 slot 2 B secondary bus
- *58        PCI 0 slot 2 C secondary bus
- *59        PCI 0 slot 2 D secondary bus
- *60        PCI 0 slot 3 A secondary bus
- *61        PCI 0 slot 3 B secondary bus
- *62        PCI 0 slot 3 C secondary bus
- *63        PCI 0 slot 3 D secondary bus
- */
-
-static void
-lynx_update_irq_hw(unsigned long bit, unsigned long mask)
-{
-       /*
-        * Write the AIR register on the T3/T4 with the
-        * address of the IC mask register (offset 0x40)
-        */
-       *(vulp)T2_AIR = 0x40;
-       mb();
-       *(vulp)T2_AIR; /* re-read to force write */
-       mb();
-       *(vulp)T2_DIR = mask;    
-       mb();
-       mb();
-}
-
-static void
-lynx_ack_irq_hw(unsigned long bit)
-{
-       *(vulp)T2_VAR = (u_long) bit;
-       mb();
-       mb();
-}
-
-static irq_swizzle_t lynx_irq_swizzle = {
-       { /* irq_to_mask */
-               -1,  6, -1,  8, 15, 12,  7,  9, /* pseudo PIC  0-7  */
-               -1, 16, 17, 18,  3, -1, 21, 22, /* pseudo PIC  8-15 */
-               -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo */
-               -1, -1, -1, -1, 28, -1, -1, -1, /* pseudo */
-               32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */
-               40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */
-               48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */
-               56, 57, 58, 59, 60, 61, 62, 63  /* mask 56-63 */
-       },
-       { /* mask_to_irq */
-               -1, -1, -1, 12, -1, -1,  1,  6, /* mask 0-7   */
-                3,  7, -1, -1,  5, -1, -1,  4, /* mask 8-15  */
-                9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */
-               -1, -1, -1, -1, 28, -1, -1, -1, /* mask 24-31 */
-               32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */
-               40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */
-               48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */
-               56, 57, 58, 59, 60, 61, 62, 63  /* mask 56-63 */
-       },
-       -1,
-       lynx_update_irq_hw,
-       lynx_ack_irq_hw
-};
-
-static void __init
-lynx_init_irq(void)
-{
-       sable_lynx_irq_swizzle = &lynx_irq_swizzle;
-       sable_lynx_init_irq(64);
-}
-
-/*
- * PCI Fixup configuration for ALPHA LYNX (2100A)
- *
- * The device to slot mapping looks like:
- *
- * Slot     Device
- *  0       none
- *  1       none
- *  2       PCI-EISA bridge
- *  3       PCI-PCI bridge
- *  4       NCR 810 (Demi-Lynx only)
- *  5       none
- *  6       PCI on board slot 4
- *  7       PCI on board slot 5
- *  8       PCI on board slot 6
- *  9       PCI on board slot 7
- *
- * And behind the PPB we have:
- *
- * 11       PCI on board slot 0
- * 12       PCI on board slot 1
- * 13       PCI on board slot 2
- * 14       PCI on board slot 3
- */
-/*
- * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
- * with the values in the irq swizzling tables above.
- */
-
-static int
-lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       static char irq_tab[19][5] = {
-               /*INT    INTA   INTB   INTC   INTD */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 13,  PCEB   */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 14,  PPB    */
-               {   28,    28,    28,    28,    28},  /* IdSel 15,  NCR demi */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none   */
-               {   32,    32,    33,    34,    35},  /* IdSel 17,  slot 4 */
-               {   36,    36,    37,    38,    39},  /* IdSel 18,  slot 5 */
-               {   40,    40,    41,    42,    43},  /* IdSel 19,  slot 6 */
-               {   44,    44,    45,    46,    47},  /* IdSel 20,  slot 7 */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 22,  none   */
-               /* The following are actually behind the PPB. */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 16   none */
-               {   28,    28,    28,    28,    28},  /* IdSel 17   NCR lynx */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 18   none */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 19   none */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 20   none */
-               {   -1,    -1,    -1,    -1,    -1},  /* IdSel 21   none */
-               {   48,    48,    49,    50,    51},  /* IdSel 22   slot 0 */
-               {   52,    52,    53,    54,    55},  /* IdSel 23   slot 1 */
-               {   56,    56,    57,    58,    59},  /* IdSel 24   slot 2 */
-               {   60,    60,    61,    62,    63}   /* IdSel 25   slot 3 */
-       };
-       const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5;
-       return COMMON_TABLE_LOOKUP;
-}
-
-static u8
-lynx_swizzle(struct pci_dev *dev, u8 *pinp)
-{
-       int slot, pin = *pinp;
-
-       if (dev->bus->number == 0) {
-               slot = PCI_SLOT(dev->devfn);
-       }
-       /* Check for the built-in bridge */
-       else if (PCI_SLOT(dev->bus->self->devfn) == 3) {
-               slot = PCI_SLOT(dev->devfn) + 11;
-       }
-       else
-       {
-               /* Must be a card-based bridge.  */
-               do {
-                       if (PCI_SLOT(dev->bus->self->devfn) == 3) {
-                               slot = PCI_SLOT(dev->devfn) + 11;
-                               break;
-                       }
-                       pin = pci_swizzle_interrupt_pin(dev, pin);
-
-                       /* Move up the chain of bridges.  */
-                       dev = dev->bus->self;
-                       /* Slot of the next bridge.  */
-                       slot = PCI_SLOT(dev->devfn);
-               } while (dev->bus->self);
-       }
-       *pinp = pin;
-       return slot;
-}
-
-#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */
-
 /***********************************************************************/
 /* GENERIC irq routines */
 
@@ -539,40 +313,7 @@ sable_lynx_init_pci(void)
  * these games with GAMMA_BIAS.
  */
 
-#if defined(CONFIG_ALPHA_GENERIC) || \
-    (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA))
-#undef GAMMA_BIAS
-#define GAMMA_BIAS 0
-struct alpha_machine_vector sable_mv __initmv = {
-       .vector_name            = "Sable",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_T2_IO,
-       .machine_check          = t2_machine_check,
-       .max_isa_dma_address    = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = EISA_DEFAULT_IO_BASE,
-       .min_mem_address        = T2_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 40,
-       .device_interrupt       = sable_lynx_srm_device_interrupt,
-
-       .init_arch              = t2_init_arch,
-       .init_irq               = sable_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = sable_lynx_init_pci,
-       .kill_arch              = t2_kill_arch,
-       .pci_map_irq            = sable_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .t2 = {
-           .gamma_bias         = 0
-       } }
-};
-ALIAS_MV(sable)
-#endif /* GENERIC || (SABLE && !GAMMA) */
-
-#if defined(CONFIG_ALPHA_GENERIC) || \
-    (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA))
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
 #undef GAMMA_BIAS
 #define GAMMA_BIAS _GAMMA_BIAS
 struct alpha_machine_vector sable_gamma_mv __initmv = {
@@ -601,35 +342,4 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
        } }
 };
 ALIAS_MV(sable_gamma)
-#endif /* GENERIC || (SABLE && GAMMA) */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
-#undef GAMMA_BIAS
-#define GAMMA_BIAS _GAMMA_BIAS
-struct alpha_machine_vector lynx_mv __initmv = {
-       .vector_name            = "Lynx",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_T2_IO,
-       .machine_check          = t2_machine_check,
-       .max_isa_dma_address    = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = EISA_DEFAULT_IO_BASE,
-       .min_mem_address        = T2_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 64,
-       .device_interrupt       = sable_lynx_srm_device_interrupt,
-
-       .init_arch              = t2_init_arch,
-       .init_irq               = lynx_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = sable_lynx_init_pci,
-       .kill_arch              = t2_kill_arch,
-       .pci_map_irq            = lynx_map_irq,
-       .pci_swizzle            = lynx_swizzle,
-
-       .sys = { .t2 = {
-           .gamma_bias         = _GAMMA_BIAS
-       } }
-};
-ALIAS_MV(lynx)
-#endif /* GENERIC || LYNX */
+#endif /* GENERIC || SABLE */
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
deleted file mode 100644 (file)
index 086488e..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *     linux/arch/alpha/kernel/sys_sio.c
- *
- *     Copyright (C) 1995 David A Rusling
- *     Copyright (C) 1996 Jay A Estabrook
- *     Copyright (C) 1998, 1999 Richard Henderson
- *
- * Code for all boards that route the PCI interrupts through the SIO
- * PCI/ISA bridge.  This includes Noname (AXPpci33), Multia (UDB),
- * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/screen_info.h>
-
-#include <asm/compiler.h>
-#include <asm/ptrace.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/mmu_context.h>
-#include <asm/io.h>
-#include <asm/core_apecs.h>
-#include <asm/core_lca.h>
-#include <asm/tlbflush.h>
-
-#include "proto.h"
-#include "irq_impl.h"
-#include "pci_impl.h"
-#include "machvec_impl.h"
-#include "pc873xx.h"
-
-#if defined(ALPHA_RESTORE_SRM_SETUP)
-/* Save LCA configuration data as the console had it set up.  */
-struct 
-{
-       unsigned int orig_route_tab; /* for SAVE/RESTORE */
-} saved_config __attribute((common));
-#endif
-
-
-static void __init
-sio_init_irq(void)
-{
-       if (alpha_using_srm)
-               alpha_mv.device_interrupt = srm_device_interrupt;
-
-       init_i8259a_irqs();
-       common_init_isa_dma();
-}
-
-static inline void __init
-alphabook1_init_arch(void)
-{
-#ifdef CONFIG_VGA_CONSOLE
-       /* The AlphaBook1 has LCD video fixed at 800x600,
-          37 rows and 100 cols. */
-       vgacon_screen_info.orig_y = 37;
-       vgacon_screen_info.orig_video_cols = 100;
-       vgacon_screen_info.orig_video_lines = 37;
-#endif
-
-       lca_init_arch();
-}
-
-
-/*
- * sio_route_tab selects irq routing in PCI/ISA bridge so that:
- *             PIRQ0 -> irq 15
- *             PIRQ1 -> irq  9
- *             PIRQ2 -> irq 10
- *             PIRQ3 -> irq 11
- *
- * This probably ought to be configurable via MILO.  For
- * example, sound boards seem to like using IRQ 9.
- *
- * This is NOT how we should do it. PIRQ0-X should have
- * their own IRQs, the way intel uses the IO-APIC IRQs.
- */
-
-static void __init
-sio_pci_route(void)
-{
-       unsigned int orig_route_tab;
-
-       /* First, ALWAYS read and print the original setting. */
-       pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
-                                 &orig_route_tab);
-       printk("%s: PIRQ original 0x%x new 0x%x\n", __func__,
-              orig_route_tab, alpha_mv.sys.sio.route_tab);
-
-#if defined(ALPHA_RESTORE_SRM_SETUP)
-       saved_config.orig_route_tab = orig_route_tab;
-#endif
-
-       /* Now override with desired setting. */
-       pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
-                                  alpha_mv.sys.sio.route_tab);
-}
-
-static bool sio_pci_dev_irq_needs_level(const struct pci_dev *dev)
-{
-       if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
-           (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
-               return false;
-
-       return true;
-}
-
-static unsigned int __init
-sio_collect_irq_levels(void)
-{
-       unsigned int level_bits = 0;
-       struct pci_dev *dev = NULL;
-
-       /* Iterate through the devices, collecting IRQ levels.  */
-       for_each_pci_dev(dev) {
-               if (!sio_pci_dev_irq_needs_level(dev))
-                       continue;
-
-               if (dev->irq)
-                       level_bits |= (1 << dev->irq);
-       }
-       return level_bits;
-}
-
-static void __sio_fixup_irq_levels(unsigned int level_bits, bool reset)
-{
-       unsigned int old_level_bits;
-
-       /*
-        * Now, make all PCI interrupts level sensitive.  Notice:
-        * these registers must be accessed byte-wise.  inw()/outw()
-        * don't work.
-        *
-        * Make sure to turn off any level bits set for IRQs 9,10,11,15,
-        *  so that the only bits getting set are for devices actually found.
-        * Note that we do preserve the remainder of the bits, which we hope
-        *  will be set correctly by ARC/SRM.
-        *
-        * Note: we at least preserve any level-set bits on AlphaBook1
-        */
-       old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
-
-       if (reset)
-               old_level_bits &= 0x71ff;
-
-       level_bits |= old_level_bits;
-
-       outb((level_bits >> 0) & 0xff, 0x4d0);
-       outb((level_bits >> 8) & 0xff, 0x4d1);
-}
-
-static inline void
-sio_fixup_irq_levels(unsigned int level_bits)
-{
-       __sio_fixup_irq_levels(level_bits, true);
-}
-
-static inline int
-noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       /*
-        * The Noname board has 5 PCI slots with each of the 4
-        * interrupt pins routed to different pins on the PCI/ISA
-        * bridge (PIRQ0-PIRQ3).  The table below is based on
-        * information available at:
-        *
-        *   http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
-        *
-        * I have no information on the Avanti interrupt routing, but
-        * the routing seems to be identical to the Noname except
-        * that the Avanti has an additional slot whose routing I'm
-        * unsure of.
-        *
-        * pirq_tab[0] is a fake entry to deal with old PCI boards
-        * that have the interrupt pin number hardwired to 0 (meaning
-        * that they use the default INTA line, if they are interrupt
-        * driven at all).
-        */
-       static char irq_tab[][5] = {
-               /*INT A   B   C   D */
-               { 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */ 
-               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
-               { 2,  2, -1, -1, -1}, /* idsel  8 (Hack: slot closest ISA) */
-               {-1, -1, -1, -1, -1}, /* idsel  9 (unused) */
-               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
-               { 0,  0,  2,  1,  0}, /* idsel 11 KN25_PCI_SLOT0 */
-               { 1,  1,  0,  2,  1}, /* idsel 12 KN25_PCI_SLOT1 */
-               { 2,  2,  1,  0,  2}, /* idsel 13 KN25_PCI_SLOT2 */
-               { 0,  0,  0,  0,  0}, /* idsel 14 AS255 TULIP */
-       };
-       const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
-       int irq = COMMON_TABLE_LOOKUP, tmp;
-       tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
-
-       irq = irq >= 0 ? tmp : -1;
-
-       /* Fixup IRQ level if an actual IRQ mapping is detected */
-       if (sio_pci_dev_irq_needs_level(dev) && irq >= 0)
-               __sio_fixup_irq_levels(1 << irq, false);
-
-       return irq;
-}
-
-static inline int
-p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       static char irq_tab[][5] = {
-               /*INT A   B   C   D */
-               { 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
-               {-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
-               { 1,  1,  2,  3,  0}, /* idsel  8 (slot A) */
-               { 2,  2,  3,  0,  1}, /* idsel  9 (slot B) */
-               {-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
-               {-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
-               { 3,  3, -1, -1, -1}, /* idsel 12 (CMD0646) */
-       };
-       const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
-       int irq = COMMON_TABLE_LOOKUP, tmp;
-       tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
-       return irq >= 0 ? tmp : -1;
-}
-
-static inline void __init
-noname_init_pci(void)
-{
-       common_init_pci();
-       sio_pci_route();
-       sio_fixup_irq_levels(sio_collect_irq_levels());
-
-       if (pc873xx_probe() == -1) {
-               printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
-       } else {
-               printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
-                       pc873xx_get_model(), pc873xx_get_base());
-
-               /* Enabling things in the Super IO chip doesn't actually
-                * configure and enable things, the legacy drivers still
-                * need to do the actual configuration and enabling.
-                * This only unblocks them.
-                */
-
-#if !defined(CONFIG_ALPHA_AVANTI)
-               /* Don't bother on the Avanti family.
-                * None of them had on-board IDE.
-                */
-               pc873xx_enable_ide();
-#endif
-               pc873xx_enable_epp19();
-       }
-}
-
-static inline void __init
-alphabook1_init_pci(void)
-{
-       struct pci_dev *dev;
-       unsigned char orig, config;
-
-       common_init_pci();
-       sio_pci_route();
-
-       /*
-        * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
-        * is sensitive to PCI bus bursts, so we must DISABLE
-        * burst mode for the NCR 8xx SCSI... :-(
-        *
-        * Note that the NCR810 SCSI driver must preserve the
-        * setting of the bit in order for this to work.  At the
-        * moment (2.0.29), ncr53c8xx.c does NOT do this, but
-        * 53c7,8xx.c DOES.
-        */
-
-       dev = NULL;
-       while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
-               if (dev->device == PCI_DEVICE_ID_NCR_53C810
-                   || dev->device == PCI_DEVICE_ID_NCR_53C815
-                   || dev->device == PCI_DEVICE_ID_NCR_53C820
-                   || dev->device == PCI_DEVICE_ID_NCR_53C825) {
-                       unsigned long io_port;
-                       unsigned char ctest4;
-
-                       io_port = dev->resource[0].start;
-                       ctest4 = inb(io_port+0x21);
-                       if (!(ctest4 & 0x80)) {
-                               printk("AlphaBook1 NCR init: setting"
-                                      " burst disable\n");
-                               outb(ctest4 | 0x80, io_port+0x21);
-                       }
-                }
-       }
-
-       /* Do not set *ANY* level triggers for AlphaBook1. */
-       sio_fixup_irq_levels(0);
-
-       /* Make sure that register PR1 indicates 1Mb mem */
-       outb(0x0f, 0x3ce); orig = inb(0x3cf);   /* read PR5  */
-       outb(0x0f, 0x3ce); outb(0x05, 0x3cf);   /* unlock PR0-4 */
-       outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
-       if ((config & 0xc0) != 0xc0) {
-               printk("AlphaBook1 VGA init: setting 1Mb memory\n");
-               config |= 0xc0;
-               outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
-       }
-       outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
-}
-
-void
-sio_kill_arch(int mode)
-{
-#if defined(ALPHA_RESTORE_SRM_SETUP)
-       /* Since we cannot read the PCI DMA Window CSRs, we
-        * cannot restore them here.
-        *
-        * However, we CAN read the PIRQ route register, so restore it
-        * now...
-        */
-       pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
-                                  saved_config.orig_route_tab);
-#endif
-}
-
-
-/*
- * The System Vectors
- */
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
-struct alpha_machine_vector alphabook1_mv __initmv = {
-       .vector_name            = "AlphaBook1",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_LCA_IO,
-       .machine_check          = lca_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = isa_device_interrupt,
-
-       .init_arch              = alphabook1_init_arch,
-       .init_irq               = sio_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = alphabook1_init_pci,
-       .kill_arch              = sio_kill_arch,
-       .pci_map_irq            = noname_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .sio = {
-               /* NCR810 SCSI is 14, PCMCIA controller is 15.  */
-               .route_tab      = 0x0e0f0a0a,
-       }}
-};
-ALIAS_MV(alphabook1)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
-struct alpha_machine_vector avanti_mv __initmv = {
-       .vector_name            = "Avanti",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = isa_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = sio_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = noname_init_pci,
-       .kill_arch              = sio_kill_arch,
-       .pci_map_irq            = noname_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .sio = {
-               .route_tab      = 0x0b0a050f, /* leave 14 for IDE, 9 for SND */
-       }}
-};
-ALIAS_MV(avanti)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
-struct alpha_machine_vector noname_mv __initmv = {
-       .vector_name            = "Noname",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_LCA_IO,
-       .machine_check          = lca_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = srm_device_interrupt,
-
-       .init_arch              = lca_init_arch,
-       .init_irq               = sio_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = noname_init_pci,
-       .kill_arch              = sio_kill_arch,
-       .pci_map_irq            = noname_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .sio = {
-               /* For UDB, the only available PCI slot must not map to IRQ 9,
-                  since that's the builtin MSS sound chip. That PCI slot
-                  will map to PIRQ1 (for INTA at least), so we give it IRQ 15
-                  instead.
-
-                  Unfortunately we have to do this for NONAME as well, since
-                  they are co-indicated when the platform type "Noname" is
-                  selected... :-(  */
-
-               .route_tab      = 0x0b0a0f0d,
-       }}
-};
-ALIAS_MV(noname)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
-struct alpha_machine_vector p2k_mv __initmv = {
-       .vector_name            = "Platform2000",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_LCA_IO,
-       .machine_check          = lca_machine_check,
-       .max_isa_dma_address    = ALPHA_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = APECS_AND_LCA_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = srm_device_interrupt,
-
-       .init_arch              = lca_init_arch,
-       .init_irq               = sio_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = noname_init_pci,
-       .kill_arch              = sio_kill_arch,
-       .pci_map_irq            = p2k_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .sio = {
-               .route_tab      = 0x0b0a090f,
-       }}
-};
-ALIAS_MV(p2k)
-#endif
-
-#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
-struct alpha_machine_vector xl_mv __initmv = {
-       .vector_name            = "XL",
-       DO_EV4_MMU,
-       DO_DEFAULT_RTC,
-       DO_APECS_IO,
-       .machine_check          = apecs_machine_check,
-       .max_isa_dma_address    = ALPHA_XL_MAX_ISA_DMA_ADDRESS,
-       .min_io_address         = DEFAULT_IO_BASE,
-       .min_mem_address        = XL_DEFAULT_MEM_BASE,
-
-       .nr_irqs                = 16,
-       .device_interrupt       = isa_device_interrupt,
-
-       .init_arch              = apecs_init_arch,
-       .init_irq               = sio_init_irq,
-       .init_rtc               = common_init_rtc,
-       .init_pci               = noname_init_pci,
-       .kill_arch              = sio_kill_arch,
-       .pci_map_irq            = noname_map_irq,
-       .pci_swizzle            = common_swizzle,
-
-       .sys = { .sio = {
-               .route_tab      = 0x0b0a090f,
-       }}
-};
-ALIAS_MV(xl)
-#endif
index 8ff110826ce21d0963869efcc169dd2155f27030..26cce7e7f70bfb547ddbd88d5a0e79c982eeefcd 100644 (file)
 542    common  fsmount                         sys_fsmount
 543    common  fspick                          sys_fspick
 544    common  pidfd_open                      sys_pidfd_open
-# 545 reserved for clone3
+545    common  clone3                          alpha_clone3
 546    common  close_range                     sys_close_range
 547    common  openat2                         sys_openat2
 548    common  pidfd_getfd                     sys_pidfd_getfd
index 7fc72aeb7398c7361bb9ae80dbf4e0f72d637e1c..6afae65e9a8b32c8a7da57c0f2a0a320b6ea60fa 100644 (file)
 
 #include "proto.h"
 
-/* Work-around for some SRMs which mishandle opDEC faults.  */
-
-static int opDEC_fix;
-
-static void
-opDEC_check(void)
-{
-       __asm__ __volatile__ (
-       /* Load the address of... */
-       "       br      $16, 1f\n"
-       /* A stub instruction fault handler.  Just add 4 to the
-          pc and continue.  */
-       "       ldq     $16, 8($sp)\n"
-       "       addq    $16, 4, $16\n"
-       "       stq     $16, 8($sp)\n"
-       "       call_pal %[rti]\n"
-       /* Install the instruction fault handler.  */
-       "1:     lda     $17, 3\n"
-       "       call_pal %[wrent]\n"
-       /* With that in place, the fault from the round-to-minf fp
-          insn will arrive either at the "lda 4" insn (bad) or one
-          past that (good).  This places the correct fixup in %0.  */
-       "       lda %[fix], 0\n"
-       "       cvttq/svm $f31,$f31\n"
-       "       lda %[fix], 4"
-       : [fix] "=r" (opDEC_fix)
-       : [rti] "n" (PAL_rti), [wrent] "n" (PAL_wrent)
-       : "$0", "$1", "$16", "$17", "$22", "$23", "$24", "$25");
-
-       if (opDEC_fix)
-               printk("opDEC fixup enabled.\n");
-}
-
 void
 dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
 {
@@ -353,32 +320,6 @@ do_entIF(unsigned long type, struct pt_regs *regs)
                return;
 
              case 4: /* opDEC */
-               if (implver() == IMPLVER_EV4) {
-                       long si_code;
-
-                       /* The some versions of SRM do not handle
-                          the opDEC properly - they return the PC of the
-                          opDEC fault, not the instruction after as the
-                          Alpha architecture requires.  Here we fix it up.
-                          We do this by intentionally causing an opDEC
-                          fault during the boot sequence and testing if
-                          we get the correct PC.  If not, we set a flag
-                          to correct it every time through.  */
-                       regs->pc += opDEC_fix; 
-                       
-                       /* EV4 does not implement anything except normal
-                          rounding.  Everything else will come here as
-                          an illegal instruction.  Emulate them.  */
-                       si_code = alpha_fp_emul(regs->pc - 4);
-                       if (si_code == 0)
-                               return;
-                       if (si_code > 0) {
-                               send_sig_fault_trapno(SIGFPE, si_code,
-                                                     (void __user *) regs->pc,
-                                                     0, current);
-                               return;
-                       }
-               }
                break;
 
              case 5: /* illoc */
@@ -979,11 +920,6 @@ trap_init(void)
        register unsigned long gptr __asm__("$29");
        wrkgp(gptr);
 
-       /* Hack for Multia (UDB) and JENSEN: some of their SRMs have
-          a bug in the handling of the opDEC fault.  Fix it up if so.  */
-       if (implver() == IMPLVER_EV4)
-               opDEC_check();
-
        wrent(entArith, 1);
        wrent(entMM, 2);
        wrent(entIF, 3);
index 6a779b9018fd151d4c527403f9aa678b8047a953..84046e730e6de8575b5439a4ae473cc0ef331d78 100644 (file)
@@ -44,17 +44,3 @@ AFLAGS___remlu.o =       -DREM -DINTSIZE
 $(addprefix $(obj)/,__divqu.o __remqu.o __divlu.o __remlu.o): \
                                                $(src)/$(ev6-y)divide.S FORCE
        $(call if_changed_rule,as_o_S)
-
-# There are direct branches between {str*cpy,str*cat} and stx*cpy.
-# Ensure the branches are within range by merging these objects.
-
-LDFLAGS_stycpy.o := -r
-LDFLAGS_styncpy.o := -r
-
-$(obj)/stycpy.o: $(obj)/strcpy.o $(obj)/$(ev67-y)strcat.o \
-                $(obj)/$(ev6-y)stxcpy.o FORCE
-       $(call if_changed,ld)
-
-$(obj)/styncpy.o: $(obj)/strncpy.o $(obj)/$(ev67-y)strncat.o \
-                $(obj)/$(ev6-y)stxncpy.o FORCE
-       $(call if_changed,ld)
index 3f35c3ed694886547e37825d95e6892ed5bee425..17fa230baeef63f9ce5ccff12d243bc64fc2188b 100644 (file)
@@ -12,6 +12,7 @@
  
 #include <linux/module.h>
 #include <linux/string.h>
+#include <net/checksum.h>
 
 #include <asm/byteorder.h>
 
index 7c08b225261c4add9b50b62a907239d30ecd4cf1..eee11fb4c7f154769f2cfeb5949a031a79612f25 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/preempt.h>
 #include <asm/thread_info.h>
+#include <asm/fpu.h>
 
 #if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
 #define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
index cbac3dc6d9635840f99c8c71c23a94edde76cc24..78b6850a9d53399c2b742d71e4e1a75bffa3a3a5 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/types.h>
 #include <linux/export.h>
+#include <linux/string.h>
 
 /*
  * This should be done in one go with ldq_u*2/mask/stq_u. Do it
@@ -150,6 +151,8 @@ static inline void __memcpy_aligned_dn (unsigned long d, unsigned long s,
        DO_REST_ALIGNED_DN(d,s,n);
 }
 
+#undef memcpy
+
 void * memcpy(void * dest, const void *src, size_t n)
 {
        if (!(((unsigned long) dest ^ (unsigned long) src) & 7)) {
diff --git a/arch/alpha/lib/stycpy.S b/arch/alpha/lib/stycpy.S
new file mode 100644 (file)
index 0000000..32ecd9c
--- /dev/null
@@ -0,0 +1,11 @@
+#include "strcpy.S"
+#ifdef CONFIG_ALPHA_EV67
+#include "ev67-strcat.S"
+#else
+#include "strcat.S"
+#endif
+#ifdef CONFIG_ALPHA_EV6
+#include "ev6-stxcpy.S"
+#else
+#include "stxcpy.S"
+#endif
diff --git a/arch/alpha/lib/styncpy.S b/arch/alpha/lib/styncpy.S
new file mode 100644 (file)
index 0000000..72fc275
--- /dev/null
@@ -0,0 +1,11 @@
+#include "strncpy.S"
+#ifdef CONFIG_ALPHA_EV67
+#include "ev67-strncat.S"
+#else
+#include "strncat.S"
+#endif
+#ifdef CONFIG_ALPHA_EV6
+#include "ev6-stxncpy.S"
+#else
+#include "stxncpy.S"
+#endif
index 4212258f3cfdc8ef83f12e679003be42ee215cd5..68d420bfd3c0d7af1acc080a3ecb50ba1e462846 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/ptrace.h>
+#include <asm/fpu.h>
 
 #include <linux/uaccess.h>
 
 #define MISC_TRAPB     0x0000
 #define MISC_EXCB      0x0400
 
-extern unsigned long alpha_read_fp_reg (unsigned long reg);
-extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
-extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
-
-
 #ifdef MODULE
 
 MODULE_DESCRIPTION("FP Software completion module");
index a155180d7a837be3ae49a929ab65a86a90d6743c..4fe618446e4cf99caff7e965e81ceb2bf74679d1 100644 (file)
@@ -33,7 +33,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 
-extern void die_if_kernel(char *,struct pt_regs *,long);
+#include "../kernel/proto.h"
 
 static struct pcb_struct original_pcb;
 
index 2d26c3397f145eef0bb9816744d481d22b4b9121..4247f19b1adc2f338af94f2fad358527f95cb856 100644 (file)
@@ -61,6 +61,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
        sun5i-a13-olinuxino.dtb \
        sun5i-a13-olinuxino-micro.dtb \
        sun5i-a13-pocketbook-touch-lux-3.dtb \
+       sun5i-a13-pocketbook-614-plus.dtb \
        sun5i-a13-q8-tablet.dtb \
        sun5i-a13-utoo-p66.dtb \
        sun5i-gr8-chip-pro.dtb \
diff --git a/arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts b/arch/arm/boot/dts/allwinner/sun5i-a13-pocketbook-614-plus.dts
new file mode 100644 (file)
index 0000000..ab8d138
--- /dev/null
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 Denis Burkov <hitechshell@mail.ru>
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       model = "PocketBook 614 Plus";
+       compatible = "pocketbook,614-plus", "allwinner,sun5i-a13";
+
+       aliases {
+               serial0 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-0 {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_POWER;
+                       linux,default-trigger = "default-on";
+                       gpios = <&pio 4 8 GPIO_ACTIVE_LOW>; /* PE8 */
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               key-0 {
+                       label = "Right";
+                       linux,code = <KEY_NEXT>;
+                       gpios = <&pio 6 9 GPIO_ACTIVE_LOW>; /* PG9 */
+               };
+
+               key-1 {
+                       label = "Left";
+                       linux,code = <KEY_PREVIOUS>;
+                       gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
+               };
+       };
+
+       reg_3v3_mmc0: regulator-mmc0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd-mmc0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&pio 4 4 GPIO_ACTIVE_LOW>; /* PE4 */
+               vin-supply = <&reg_vcc3v3>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       axp209: pmic@34 {
+               compatible = "x-powers,axp209";
+               reg = <0x34>;
+               interrupts = <0>;
+       };
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+       status = "okay";
+
+       pcf8563: rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+       };
+};
+
+&lradc {
+       vref-supply = <&reg_ldo2>;
+       status = "okay";
+
+       button-300 {
+               label = "Down";
+               linux,code = <KEY_DOWN>;
+               channel = <0>;
+               voltage = <300000>;
+       };
+
+       button-700 {
+               label = "Up";
+               linux,code = <KEY_UP>;
+               channel = <0>;
+               voltage = <700000>;
+       };
+
+       button-1000 {
+               label = "Left";
+               linux,code = <KEY_LEFT>;
+               channel = <0>;
+               voltage = <1000000>;
+       };
+
+       button-1200 {
+               label = "Menu";
+               linux,code = <KEY_MENU>;
+               channel = <0>;
+               voltage = <1200000>;
+       };
+
+       button-1500 {
+               label = "Right";
+               linux,code = <KEY_RIGHT>;
+               channel = <0>;
+               voltage = <1500000>;
+       };
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_3v3_mmc0>;
+       bus-width = <4>;
+       cd-gpios = <&pio 6 0 GPIO_ACTIVE_LOW>; /* PG0 */
+       status = "okay";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_4bit_pc_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&otg_sram {
+       status = "okay";
+};
+
+&reg_dcdc2 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1500000>;
+       regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+       regulator-always-on;
+       regulator-min-microvolt = <1000000>;
+       regulator-max-microvolt = <1400000>;
+       regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+       regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+       regulator-always-on;
+       regulator-min-microvolt = <3000000>;
+       regulator-max-microvolt = <3000000>;
+       regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+       status = "okay";
+       gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+};
+
+&reg_usb1_vbus {
+       gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pg_pins>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usb_power_supply {
+       status = "okay";
+};
+
+&battery_power_supply {
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+       usb0_vbus_det-gpios = <&axp_gpio 1 GPIO_ACTIVE_HIGH>;
+       usb0_vbus-supply = <&reg_usb0_vbus>;
+       usb1_vbus-supply = <&reg_usb1_vbus>;
+       status = "okay";
+};
index 3325ab07094a07963b693ffa1b3e38dd60ef0134..2c9152b151be294f987d536ec4e231e29e8fb457 100644 (file)
                        };
 
                        trips {
-                               cpu_alert0: cpu_alert0 {
+                               cpu_alert0: cpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <85000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu_crit: cpu_crit {
+                               cpu_crit: cpu-crit {
                                        /* milliCelsius */
                                        temperature = <100000>;
                                        hysteresis = <2000>;
index 5c3562b85a5bf95003b63013ba5d6e43cbda2d71..ffbd99c176db19f289131a81aaf20c6994f4069e 100644 (file)
@@ -77,7 +77,7 @@
                };
        };
 
-       mmc0_pwrseq: mmc0_pwrseq {
+       mmc0_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */
        };
index 4192c23848c316c29ed874ebb85b52ab64c8ce11..8c784a2c086edb301d599f7c66e089f289ea8a9b 100644 (file)
@@ -77,7 +77,7 @@
                };
        };
 
-       mmc0_pwrseq: mmc0_pwrseq {
+       mmc0_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 2 19 GPIO_ACTIVE_LOW>; /* PC19 */
        };
index 236ebfc061924bf694b6c897f872beb8c5d75d20..5bce7a32651ed2bb93c35618ea70985ab9e3e0fe 100644 (file)
                };
        };
 
-       reg_vga_3v3: vga_3v3_regulator {
+       reg_vga_3v3: vga-3v3-regulator {
                compatible = "regulator-fixed";
                regulator-name = "vga-3v3";
                regulator-min-microvolt = <3300000>;
                gpio = <&pio 7 25 GPIO_ACTIVE_HIGH>; /* PH25 */
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 */
        };
index 5cce4918f84c96170319d01fddfcbb2cb8073362..f0145d6b9c531879d9fdac7e2ded28cd6af7e539 100644 (file)
                        };
 
                        trips {
-                               cpu_alert0: cpu_alert0 {
+                               cpu_alert0: cpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <70000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu_crit: cpu_crit {
+                               cpu_crit: cpu-crit {
                                        /* milliCelsius */
                                        temperature = <100000>;
                                        hysteresis = <2000>;
                        compatible = "allwinner,sun6i-a31-prcm";
                        reg = <0x01f01400 0x200>;
 
-                       ar100: ar100_clk {
+                       ar100: ar100-clk {
                                compatible = "allwinner,sun6i-a31-ar100-clk";
                                #clock-cells = <0>;
                                clocks = <&rtc CLK_OSC32K>, <&osc24M>,
                                clock-output-names = "ar100";
                        };
 
-                       ahb0: ahb0_clk {
+                       ahb0: ahb0-clk {
                                compatible = "fixed-factor-clock";
                                #clock-cells = <0>;
                                clock-div = <1>;
                                clock-output-names = "ahb0";
                        };
 
-                       apb0: apb0_clk {
+                       apb0: apb0-clk {
                                compatible = "allwinner,sun6i-a31-apb0-clk";
                                #clock-cells = <0>;
                                clocks = <&ahb0>;
                                clock-output-names = "apb0";
                        };
 
-                       apb0_gates: apb0_gates_clk {
+                       apb0_gates: apb0-gates-clk {
                                compatible = "allwinner,sun6i-a31-apb0-gates-clk";
                                #clock-cells = <1>;
                                clocks = <&apb0>;
                                                "apb0_i2c";
                        };
 
-                       ir_clk: ir_clk {
+                       ir_clk: ir-clk {
                                #clock-cells = <0>;
                                compatible = "allwinner,sun4i-a10-mod0-clk";
                                clocks = <&rtc CLK_OSC32K>, <&osc24M>;
                                clock-output-names = "ir";
                        };
 
-                       apb0_rst: apb0_rst {
+                       apb0_rst: apb0-rst {
                                compatible = "allwinner,sun6i-a31-clock-reset";
                                #reset-cells = <1>;
                        };
index 96554ab4f6d3373eac165bb72f6ddc215fe3d5fd..f63d67ec98875515971e3849e1919c97642da396 100644 (file)
@@ -75,7 +75,7 @@
                };
        };
 
-       mmc2_pwrseq: mmc2_pwrseq {
+       mmc2_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 WIFI_EN */
        };
index caa935ca4f190bccf9f8ddac7ab8ddb89bb6633e..f2d7fab9978d47b94c360b8b98a009925123f1d8 100644 (file)
@@ -86,7 +86,7 @@
                };
        };
 
-       mmc3_pwrseq: mmc3_pwrseq {
+       mmc3_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 7 22 GPIO_ACTIVE_LOW>; /* PH22 WL-PMU-EN */
        };
index 52160e3683049aa83e4c106e8506a04a87691fef..be9b31d0f4b57b20d8eae023ffc2a79b22c36802 100644 (file)
@@ -96,7 +96,7 @@
                };
        };
 
-       mmc3_pwrseq: mmc3_pwrseq {
+       mmc3_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */
                clocks = <&ccu CLK_OUT_A>;
index 3def2a33059810a3b3e18c4d491aad6c54998ebd..f1e26b75cd902d5e4ca260b3fbd78bcb5adb886c 100644 (file)
@@ -65,7 +65,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       reg_mmc3_vdd: mmc3_vdd {
+       reg_mmc3_vdd: regulator-mmc3-vdd {
                compatible = "regulator-fixed";
                regulator-name = "mmc3_vdd";
                regulator-min-microvolt = <3000000>;
@@ -74,7 +74,7 @@
                gpio = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
        };
 
-       reg_gmac_vdd: gmac_vdd {
+       reg_gmac_vdd: regulator-gmac-vdd {
                compatible = "regulator-fixed";
                regulator-name = "gmac_vdd";
                regulator-min-microvolt = <3000000>;
index 20bf09b2226cf4780a8e7642ed5d1954c4966632..fb835730bbc49ec66b1bde2d7faed49225406bda 100644 (file)
@@ -14,7 +14,7 @@
        model = "Olimex A20-Olimex-SOM-EVB-eMMC";
        compatible = "olimex,a20-olimex-som-evb-emmc", "allwinner,sun7i-a20";
 
-       mmc2_pwrseq: mmc2_pwrseq {
+       mmc2_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&pio 2 18 GPIO_ACTIVE_LOW>;
        };
index a59755a2e7a9db9e2fa8baf06f18571663da78ad..e8977c2fe7986f80f6c96e6cda9eccbfd069e242 100644 (file)
@@ -13,7 +13,7 @@
        model = "Olimex A20-SOM204-EVB-eMMC";
        compatible = "olimex,a20-olimex-som204-evb-emmc", "allwinner,sun7i-a20";
 
-       mmc2_pwrseq: mmc2_pwrseq {
+       mmc2_pwrseq: pwrseq-1 {
                compatible = "mmc-pwrseq-emmc";
                reset-gpios = <&pio 2 16 GPIO_ACTIVE_LOW>;
        };
index 54af6c18075b50dca6f008e0d5f3d61333ddde41..a55406657449d848841707768394f7dea3763384 100644 (file)
@@ -65,7 +65,7 @@
                };
        };
 
-       rtl_pwrseq: rtl_pwrseq {
+       rtl_pwrseq: pwrseq-0 {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 6 9 GPIO_ACTIVE_LOW>;
        };
        non-removable;
        status = "okay";
 
-       rtl8723bs: sdio_wifi@1 {
+       rtl8723bs: wifi@1 {
                reg = <1>;
        };
 };
index ecb91fb899ff3db1d1bb0bc54da12ce069be7586..435a189332e8f1aa4da54f295a0d0d4902afb70b 100644 (file)
@@ -82,7 +82,7 @@
                };
        };
 
-       reg_axp_ipsout: axp_ipsout {
+       reg_axp_ipsout: regulator-axp-ipsout {
                compatible = "regulator-fixed";
                regulator-name = "axp-ipsout";
                regulator-min-microvolt = <5000000>;
index 3bfae98f3cc3a18e6d312ced1337acb9340e397f..29199b6a3b4a1eeb88ed2d7a77323414a1a1d5a9 100644 (file)
@@ -60,7 +60,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       mmc3_pwrseq: mmc3_pwrseq {
+       mmc3_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 WIFI_EN */
        };
index 5574299685ab5c614fa8aa0df413aec798ea9c94..5f44f09c554528dc6ffda06f7713440ab56426af 100644 (file)
                        };
 
                        trips {
-                               cpu_alert0: cpu_alert0 {
+                               cpu_alert0: cpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <75000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu_crit: cpu_crit {
+                               cpu_crit: cpu-crit {
                                        /* milliCelsius */
                                        temperature = <100000>;
                                        hysteresis = <2000>;
index cd4bf60dbb3cb1bdfbf9224e5f94f4933a69c89d..2af8382ccdf5769b9e3ae681c45b529e6d0aa821 100644 (file)
                #size-cells = <1>;
                ranges;
 
-               osc24M: osc24M_clk {
+               osc24M: osc24M-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <24000000>;
                        clock-output-names = "osc24M";
                };
 
-               ext_osc32k: ext_osc32k_clk {
+               ext_osc32k: ext-osc32k-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
                        compatible = "allwinner,sun8i-a23-prcm";
                        reg = <0x01f01400 0x200>;
 
-                       ar100: ar100_clk {
+                       ar100: ar100-clk {
                                compatible = "fixed-factor-clock";
                                #clock-cells = <0>;
                                clock-div = <1>;
                                clock-output-names = "ar100";
                        };
 
-                       ahb0: ahb0_clk {
+                       ahb0: ahb0-clk {
                                compatible = "fixed-factor-clock";
                                #clock-cells = <0>;
                                clock-div = <1>;
                                clock-output-names = "ahb0";
                        };
 
-                       apb0: apb0_clk {
+                       apb0: apb0-clk {
                                compatible = "allwinner,sun8i-a23-apb0-clk";
                                #clock-cells = <0>;
                                clocks = <&ahb0>;
                                clock-output-names = "apb0";
                        };
 
-                       apb0_gates: apb0_gates_clk {
+                       apb0_gates: apb0-gates-clk {
                                compatible = "allwinner,sun8i-a23-apb0-gates-clk";
                                #clock-cells = <1>;
                                clocks = <&apb0>;
                                                "apb0_i2c";
                        };
 
-                       apb0_rst: apb0_rst {
+                       apb0_rst: apb0-rst {
                                compatible = "allwinner,sun6i-a31-clock-reset";
                                #reset-cells = <1>;
                        };
index d5f6aebd7216d2cc910d44919355bd622d98d480..0c585a6d990d4068a356214f3b5c87aa658e2f6b 100644 (file)
@@ -52,7 +52,7 @@
                ethernet0 = &esp8089;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
                /* The esp8089 needs 200 ms after driving wifi-en high */
@@ -76,7 +76,7 @@
        non-removable;
        status = "okay";
 
-       esp8089: sdio_wifi@1 {
+       esp8089: wifi@1 {
                compatible = "esp,esp8089";
                reg = <1>;
                esp,crystal-26M-en = <2>;
index 9f9232a2fefbbbe86225eea83aa5873c2f0bde58..63cb4e194a03d6f01f8fcb42e5245b36e9f8169b 100644 (file)
@@ -52,7 +52,7 @@
                ethernet0 = &esp8089;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL6 */
                /* The esp8089 needs 200 ms after driving wifi-en high */
@@ -69,7 +69,7 @@
        non-removable;
        status = "okay";
 
-       esp8089: sdio_wifi@1 {
+       esp8089: wifi@1 {
                compatible = "esp,esp8089";
                reg = <1>;
                esp,crystal-26M-en = <2>;
index 2dfdd0a3151e84863a38937c9b33346df5f74bd0..f00ce03ffc8477cbb8edf2c6d84d1e7cd2067d9c 100644 (file)
@@ -85,7 +85,7 @@
        non-removable;
        status = "okay";
 
-       rtl8703as: sdio_wifi@1 {
+       rtl8703as: wifi@1 {
                reg = <1>;
        };
 };
index 065cb620aa992431281317c3e9681018a77f153c..162ba93f748469ee247ee27639a2b0ebd55cd686 100644 (file)
@@ -78,7 +78,7 @@
        non-removable;
        status = "okay";
 
-       rtl8723bs: sdio_wifi@1 {
+       rtl8723bs: wifi@1 {
                reg = <1>;
        };
 };
index 30fdd2703b1ff493f06d4c44f566608172daf45e..36b2d78cdab9ec5770a458a891269547af68361e 100644 (file)
                        };
 
                        trips {
-                               cpu_alert0: cpu_alert0 {
+                               cpu_alert0: cpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <75000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               gpu_alert0: gpu_alert0 {
+                               gpu_alert0: gpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <85000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu_alert1: cpu_alert1 {
+                               cpu_alert1: cpu-alert1 {
                                        /* milliCelsius */
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
 
-                               gpu_alert1: gpu_alert1 {
+                               gpu_alert1: gpu-alert1 {
                                        /* milliCelsius */
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
 
-                               cpu_crit: cpu_crit {
+                               cpu_crit: cpu-crit {
                                        /* milliCelsius */
                                        temperature = <110000>;
                                        hysteresis = <2000>;
index 8d56b103f063049dac71fa02439b63ed7e70fd32..32e811fa23e2289ff96a7c09f819d224690c0209 100644 (file)
@@ -95,7 +95,7 @@
                gpio = <&pio 3 24 GPIO_ACTIVE_HIGH>; /* PD24 */
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&ac100_rtc 1>;
                clock-names = "ext_clock";
index 870993393fc2439953297003869052b28f6b4b5a..d5e6ddaffbce39c02e1aae15110e24af84d0408e 100644 (file)
                compatible = "linux,spdif-dit";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&ac100_rtc 1>;
                clock-names = "ext_clock";
index a7d4ca308990c2082985359a84c874cfe201c8ac..43982b106a4db8be70223d4f9cfd271e8fb1282f 100644 (file)
                vin-supply = <&reg_vbat>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 WL-PMU-EN */
 
index 94eb3bfc989e2913fb8ce79b6fe1358bcbced75c..addf0cb0f465d186ffac7d7c99da3b314d8fed51 100644 (file)
                ranges;
 
                /* TODO: PRCM block has a mux for this. */
-               osc24M: osc24M_clk {
+               osc24M: osc24M-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <24000000>;
                 * It is an internal RC-based oscillator.
                 * TODO: Its controls are in the PRCM block.
                 */
-               osc16M: osc16M_clk {
+               osc16M: osc16M-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <16000000>;
                        clock-output-names = "osc16M";
                };
 
-               osc16Md512: osc16Md512_clk {
+               osc16Md512: osc16Md512-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-factor-clock";
                        clock-div = <512>;
                        #reset-cells = <1>;
                };
 
-               r_cpucfg@1f01c00 {
+               cpucfg@1f01c00 {
                        compatible = "allwinner,sun8i-a83t-r-cpucfg";
                        reg = <0x1f01c00 0x400>;
                };
index d729b7c705db54d9cf9f40cda299fc71abc1cef1..d3a7c9fa23e4460da0bda00330f94a5057e31fba 100644 (file)
                cpu-supply = <&reg_vcc1v2>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index 3356f4210d45b4e055d61f29ef72fad0238045fc..79b03b31c5eb8024d80e6395ed750f243d4cfae4 100644 (file)
 /* Orange Pi R1 is based on Orange Pi Zero design */
 #include "sun8i-h2-plus-orangepi-zero.dts"
 
+/delete-node/ &reg_vcc_wifi;
+
 / {
        model = "Xunlong Orange Pi R1";
        compatible = "xunlong,orangepi-r1", "allwinner,sun8i-h2-plus";
 
-       /delete-node/ reg_vcc_wifi;
 
        /*
         * Ths pin of this regulator is the same with the Wi-Fi extra
@@ -89,7 +90,7 @@
        vmmc-supply = <&reg_vcc3v3>;
        vqmmc-supply = <&reg_vcc3v3>;
 
-       rtl8189etv: sdio_wifi@1 {
+       rtl8189etv: wifi@1 {
                reg = <1>;
        };
 };
index 3706216ffb40bac94501f3f4f529e2d5f7a87cfc..1b001f2ad0efd2e77218742efe6d8edfdd18a816 100644 (file)
@@ -80,7 +80,7 @@
                };
        };
 
-       reg_vcc_wifi: reg_vcc_wifi {
+       reg_vcc_wifi: reg-vcc-wifi {
                compatible = "regulator-fixed";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
                states = <1100000 0>, <1300000 1>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;
                post-power-on-delay-ms = <200>;
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       xr819: sdio_wifi@1 {
+       xr819: wifi@1 {
                reg = <1>;
        };
 };
index a6d38ecee141d438898325f08bcd5e595d425950..5b77300307dea7fdbe7db7d610ceffaf9b1e97b7 100644 (file)
                compatible = "linux,spdif-dit";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       sdiowifi: sdio_wifi@1 {
+       sdiowifi: wifi@1 {
                reg = <1>;
        };
 };
index 343b02b97155539c4b9b8a0356647c1dda691b17..2b0566d4b3867456af1800fb50d9ba23613acf39 100644 (file)
@@ -87,7 +87,7 @@
                vin-supply = <&reg_vcc5v0>;
         };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
        non-removable;
        status = "okay";
 
-       sdio_wifi: sdio_wifi@1 {
+       sdio_wifi: wifi@1 {
                reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&pio>;
index 4ba533b0340f220c9ce38aba9a693bcf42e8d1a4..59bd0746acf82b4fe67c18766a8342b5bac1bc4f 100644 (file)
@@ -62,7 +62,7 @@
                gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
        };
        non-removable;
        status = "okay";
 
-       sdio_wifi: sdio_wifi@1 {
+       sdio_wifi: wifi@1 {
                reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&pio>;
index 9e1a33f94cadc58a56e3bb92b6bcdda8341d830b..6d85370e04f16bdeddd959aa9f0d058099a040ce 100644 (file)
@@ -73,7 +73,7 @@
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
        };
index 42cd1131adf3d098fb434c9e4126a6d88d870db1..870649760f7075c1de98036944e2402e5c3563d0 100644 (file)
@@ -43,7 +43,7 @@
                         <1300000 0x1>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index f1f9dbead32a93e19e48f627b82c76ea9dd9c9f4..d2ae47b074bf79f02bc6b91524ab169bd4131d51 100644 (file)
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 WIFI_EN */
        };
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       rtl8189: sdio_wifi@1 {
+       rtl8189: wifi@1 {
                reg = <1>;
        };
 };
index 305b34a321f5cc21ee38986b6d53f93bda6ae3a1..6a4316a52469ae125f7a0eb03b6cc2edafd809e1 100644 (file)
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       rtl8189ftv: sdio_wifi@1 {
+       rtl8189ftv: wifi@1 {
                reg = <1>;
        };
 };
index babf4cf1b2f6897cda3605aff044cbea96263c97..8a49b3376dfc9de7aded632dfd2ecda335ff2978 100644 (file)
@@ -63,7 +63,7 @@
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       rtl8189ftv: sdio_wifi@1 {
+       rtl8189ftv: wifi@1 {
                reg = <1>;
        };
 };
index 561ea1d2f861c437db66bea4125dfb4d8ba88ff5..7a6444a10e2534458b7380882ea4fd42bd54fea8 100644 (file)
@@ -92,7 +92,7 @@
                regulator-max-microvolt = <3300000>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
                post-power-on-delay-ms = <200>;
index 3d9a1524e17e4f613fd782d1807dff9a80ce3916..272584881bb214a201ad6b07715258e18d303439 100644 (file)
@@ -62,7 +62,7 @@
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                /*
                 * Q8 boards use various PL# pins as wifi-en. On other boards
@@ -94,7 +94,7 @@
        non-removable;
        status = "okay";
 
-       sdio_wifi: sdio_wifi@1 {
+       sdio_wifi: wifi@1 {
                reg = <1>;
        };
 };
index bc394686fedbb8fc8c9c514113eebb30c940b052..f4bf46b35bec8a7c0bb9de21ad452d4bed8e03e1 100644 (file)
@@ -88,7 +88,7 @@
                regulator-max-microvolt = <5000000>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index 95543a9c21182fd74b02c9cb746563edb29855d2..75067522ff59bbceaa66e8d169be20df982d2e58 100644 (file)
@@ -75,7 +75,7 @@
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 6 GPIO_ACTIVE_LOW>; /* PL06 */
        };
index 28197bbcb1d56ad3604f60a6172d0c9f8cf4586a..cd2351acc32f8b2d148f6dd359f6fc9c8c9406fc 100644 (file)
                enable-active-high;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
                clocks = <&ccu CLK_OUTA>;
index 0bd1336206b839594668a3192dd59461cef2b0d2..15b0b4de626af30557c83b0840f841bb5f355b9c 100644 (file)
@@ -62,7 +62,7 @@
                regulator-max-microvolt = <5000000>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; // PB10 WIFI_EN
                clocks = <&ccu CLK_OUTA>;
index 20966e954eda89cf309a97629ec10e8cda92dd31..e0d4404b5957d3270c497aa95d3a9bfcb9262260 100644 (file)
@@ -51,7 +51,7 @@
                startup-delay-us = <200000>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 1 3 GPIO_ACTIVE_LOW>; /* PB3 WIFI-RST */
                post-power-on-delay-ms = <200>;
index e8a04476b776251312ce5d36cf2dea8c503f5a71..9e13c2aa89112779925d65a428167076d9a91db7 100644 (file)
@@ -98,7 +98,7 @@
                #size-cells = <1>;
                ranges;
 
-               osc24M: osc24M_clk {
+               osc24M: osc24M-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <24000000>;
                        clock-output-names = "osc24M";
                };
 
-               osc32k: osc32k_clk {
+               osc32k: osc32k-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
index 434871040aca00b07d74f42eae522b5d05ff6239..6575ef2744530f8d024e140be0d16f57efd42098 100644 (file)
@@ -94,7 +94,7 @@
                enable-active-high;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 6 10 GPIO_ACTIVE_LOW>; /* PG10 WIFI_EN */
                clocks = <&ccu CLK_OUTA>;
index 7d3f3300f4316d5710b868646c3e6365cc58de70..a1ae0929cec9d22704ebea75c8ecfae2a6617008 100644 (file)
                 * The actual TX clock rate is not controlled by the
                 * gmac_tx clock.
                 */
-               mii_phy_tx_clk: mii_phy_tx_clk {
+               mii_phy_tx_clk: mii-phy-tx-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <25000000>;
                        clock-output-names = "mii_phy_tx";
                };
 
-               gmac_int_tx_clk: gmac_int_tx_clk {
+               gmac_int_tx_clk: gmac-int-tx-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <125000000>;
index 1d1d127cf38f5c8e473f6e06a13707fadfe39a37..873817ddb4eae6a24283ce9e29f3ef8853ab95fd 100644 (file)
@@ -98,7 +98,7 @@
                gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index 60804b0e6c56a62f9049f4a51354747b0d195b26..be5f5528a118320f217551f9c098b6707247c8f3 100644 (file)
@@ -18,7 +18,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 2 7 GPIO_ACTIVE_LOW>; /* PC7 */
                post-power-on-delay-ms = <200>;
index ade1cd50e445706d9aaac80eb5f1a553f10b2d9f..7df60515a90320655b5203eecd6cbcab878def41 100644 (file)
@@ -83,7 +83,7 @@
                #size-cells = <1>;
                ranges;
 
-               osc24M: osc24M_clk {
+               osc24M: osc24M-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <24000000>;
@@ -91,7 +91,7 @@
                        clock-output-names = "osc24M";
                };
 
-               osc32k: osc32k_clk {
+               osc32k: osc32k-clk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
                        clock-frequency = <32768>;
index 4554abf0c7cdf2153356735c330ae43a6767606c..9aa2de3723b53057189b97c8d14652978db8298c 100644 (file)
 
        /* IPB PMIC */
        lm25066@40 {
-               compatible = "lm25066";
+               compatible = "ti,lm25066";
                reg = <0x40>;
                shunt-resistor-micro-ohms = <1000>;
        };
 
        /* 12VSB PMIC */
        lm25066@41 {
-               compatible = "lm25066";
+               compatible = "ti,lm25066";
                reg = <0x41>;
                shunt-resistor-micro-ohms = <10000>;
        };
index 6600f7e9bf5ed4dbb6c228fa1af831a5e2580a25..e830fec0570f8c1d774d2c338f6302a12ca29c52 100644 (file)
@@ -14,7 +14,7 @@
 
 #define EFUSE(hexaddr, num)                                                    \
        efuse@##hexaddr {                                                       \
-               compatible = "lm25066";                                         \
+               compatible = "ti,lm25066";                                      \
                reg = <0x##hexaddr>;                                            \
                shunt-resistor-micro-ohms = <675>;                              \
                regulators {                                                    \
index 7099d9560033093ff7130b008b2f9e22a80f19e4..5881bcc95eba6bbd4f4dfd6e0d00365db25f7094 100644 (file)
@@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm47081-luxul-xap-1410.dtb \
        bcm47081-luxul-xwr-1200.dtb \
        bcm47081-tplink-archer-c5-v2.dtb \
+       bcm4709-asus-rt-ac3200.dtb \
        bcm4709-asus-rt-ac87u.dtb \
        bcm4709-buffalo-wxr-1900dhp.dtb \
        bcm4709-linksys-ea9200.dtb \
@@ -71,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
        bcm4709-netgear-r8000.dtb \
        bcm4709-tplink-archer-c9-v1.dtb \
        bcm47094-asus-rt-ac3100.dtb \
+       bcm47094-asus-rt-ac5300.dtb \
        bcm47094-asus-rt-ac88u.dtb \
        bcm47094-dlink-dir-885l.dtb \
        bcm47094-dlink-dir-890l.dtb \
index d5f8823230db9dd1332c8ffbb5cb76e7fe71b506..353bb50ce5425c9763f1a1f9d067bf1055ce4bb2 100644 (file)
@@ -5,6 +5,7 @@
 #include "bcm283x-rpi-led-deprecated.dtsi"
 #include "bcm283x-rpi-usb-peripheral.dtsi"
 #include "bcm283x-rpi-wifi-bt.dtsi"
+#include <dt-bindings/leds/common.h>
 
 / {
        compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
                stdout-path = "serial1:115200n8";
        };
 
+       cam1_reg: regulator-cam1 {
+               compatible = "regulator-fixed";
+               regulator-name = "cam1-reg";
+               enable-active-high;
+               gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
+       };
+
        sd_io_1v8_reg: regulator-sd-io-1v8 {
                compatible = "regulator-gpio";
                regulator-name = "vdd-sd-io";
        phy1: ethernet-phy@1 {
                /* No PHY interrupt */
                reg = <0x1>;
+
+               leds {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       /* LED1 */
+                       led@0 {
+                               reg = <0>;
+                               color = <LED_COLOR_ID_GREEN>;
+                               function = LED_FUNCTION_LAN;
+                               default-state = "keep";
+                       };
+
+                       /* LED2 */
+                       led@1 {
+                               reg = <1>;
+                               color = <LED_COLOR_ID_AMBER>;
+                               function = LED_FUNCTION_LAN;
+                               default-state = "keep";
+                       };
+               };
        };
 };
 
index 5a2869a18bd555cbacdb92c5a7cdee18cf6ef842..ca9be91b4f365475610bf2f50ef4a44f94b8310e 100644 (file)
@@ -30,6 +30,7 @@
 
 &genet_mdio {
        clock-frequency = <1950000>;
+       /delete-node/ leds;
 };
 
 &led_pwr {
index d7ba02f586d30f6e37b4b2eeb4bb4860a6eee775..6bc77dd48c0d9b26b19968cb6f337fb8c03ab421 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
+#include <dt-bindings/leds/common.h>
 #include "bcm2711-rpi-cm4.dtsi"
 #include "bcm283x-rpi-led-deprecated.dtsi"
 #include "bcm283x-rpi-usb-host.dtsi"
        status = "okay";
 };
 
+&i2c0_1 {
+       rtc@51 {
+               /* Attention: An alarm resets the machine */
+               compatible = "nxp,pcf85063a";
+               reg = <0x51>;
+               quartz-load-femtofarads = <7000>;
+       };
+};
+
+&phy1 {
+       leds {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               /* LED2 */
+               led@1 {
+                       reg = <1>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_LAN;
+                       default-state = "keep";
+               };
+
+               /* LED3 */
+               led@2 {
+                       reg = <2>;
+                       color = <LED_COLOR_ID_AMBER>;
+                       function = LED_FUNCTION_LAN;
+                       default-state = "keep";
+               };
+       };
+};
+
 &led_act {
        gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
 };
index d233a191c139362d36e581ed7b9222b0ebee3189..6bf4241fe3b737a9a397fcadc2d2b1d51df08473 100644 (file)
                pcie0 = &pcie0;
                blconfig = &blconfig;
        };
-};
 
-&firmware {
-       firmware_clocks: clocks {
-               compatible = "raspberrypi,firmware-clocks";
-               #clock-cells = <1>;
+       i2c0mux: i2c-mux0 {
+               compatible = "i2c-mux-pinctrl";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               i2c-parent = <&i2c0>;
+
+               pinctrl-names = "i2c0", "i2c0-vc";
+               pinctrl-0 = <&i2c0_gpio0>;
+               pinctrl-1 = <&i2c0_gpio44>;
+
+               i2c0_0: i2c@0 {
+                       reg = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c0_1: i2c@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
        };
+};
 
+&firmware {
        expgpio: gpio {
                compatible = "raspberrypi,firmware-gpio";
                gpio-controller;
        clocks = <&firmware_clocks 4>;
 };
 
+&i2c0 {
+       /delete-property/ pinctrl-names;
+       /delete-property/ pinctrl-0;
+};
+
 &rmem {
        /*
         * RPi4's co-processor will copy the board's bootloader configuration
index 22c7f1561344ed57978b4d91d6cdff6a6a84e9ff..e4e42af21ef3a4399fa697a4359b707f4189c484 100644 (file)
                };
        };
 
-       arm-pmu {
-               compatible = "arm,cortex-a72-pmu", "arm,armv8-pmuv3";
+       pmu {
+               compatible = "arm,cortex-a72-pmu";
                interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
                        <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
                        <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
        #address-cells = <2>;
 };
 
+&csi0 {
+       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&csi1 {
+       interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+};
+
 &cma {
        /*
         * arm64 reserves the CMA by default somewhere in ZONE_DMA32,
index 4e7b4a592da7c3284358222b92781af624d90ec4..8b3c21d9f333a16ed94d3f84ea55c54adb9756b3 100644 (file)
@@ -7,13 +7,6 @@
 
 #include <dt-bindings/power/raspberrypi-power.h>
 
-&firmware {
-       firmware_clocks: clocks {
-               compatible = "raspberrypi,firmware-clocks";
-               #clock-cells = <1>;
-       };
-};
-
 &hdmi {
        clocks = <&firmware_clocks 9>,
                 <&firmware_clocks 13>;
index f0acc9390f317c16d7fa148be4861a7eb2269d72..e9bf41b9f5c1814ae79f7b2308db885bf20d50ca 100644 (file)
@@ -4,11 +4,12 @@
        soc {
                firmware: firmware {
                        compatible = "raspberrypi,bcm2835-firmware", "simple-mfd";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
                        mboxes = <&mailbox>;
-                       dma-ranges;
+
+                       firmware_clocks: clocks {
+                               compatible = "raspberrypi,firmware-clocks";
+                               #clock-cells = <1>;
+                       };
                };
 
                power: power {
        };
 };
 
+&csi0 {
+       clocks = <&clocks BCM2835_CLOCK_CAM0>,
+                <&firmware_clocks 4>;
+       clock-names = "lp", "vpu";
+       power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
+};
+
+&csi1 {
+       clocks = <&clocks BCM2835_CLOCK_CAM1>,
+                <&firmware_clocks 4>;
+       clock-names = "lp", "vpu";
+       power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
+};
+
 &gpio {
        gpioout: gpioout {
                brcm,pins = <6>;
index 2ca8a2505a4db87fc6412028c8205b736b29f32f..69b0919f1324abd5d875c70936de1b7f22e3e66d 100644 (file)
                        status = "disabled";
                };
 
+               csi0: csi@7e800000 {
+                       compatible = "brcm,bcm2835-unicam";
+                       reg = <0x7e800000 0x800>,
+                             <0x7e802000 0x4>;
+                       reg-names = "unicam", "cmi";
+                       interrupts = <2 6>;
+                       brcm,num-data-lanes = <2>;
+                       status = "disabled";
+                       port {
+                       };
+               };
+
+               csi1: csi@7e801000 {
+                       compatible = "brcm,bcm2835-unicam";
+                       reg = <0x7e801000 0x800>,
+                             <0x7e802004 0x4>;
+                       reg-names = "unicam", "cmi";
+                       interrupts = <2 7>;
+                       brcm,num-data-lanes = <4>;
+                       status = "disabled";
+                       port {
+                       };
+               };
+
                i2c1: i2c@7e804000 {
                        compatible = "brcm,bcm2835-i2c";
                        reg = <0x7e804000 0x1000>;
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts b/arch/arm/boot/dts/broadcom/bcm4709-asus-rt-ac3200.dts
new file mode 100644 (file)
index 0000000..53cb0c5
--- /dev/null
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Author: Tom Brautaset <tbrautaset@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm4709.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+       compatible = "asus,rt-ac3200", "brcm,bcm4709", "brcm,bcm4708";
+       model = "ASUS RT-AC3200";
+
+       memory@0 {
+               reg = <0x00000000 0x08000000>,
+                     <0x88000000 0x08000000>;
+               device_type = "memory";
+       };
+
+       nvram@1c080000 {
+               compatible = "brcm,nvram";
+               reg = <0x1c080000 0x00180000>;
+
+               et0macaddr: et0macaddr {
+                       #nvmem-cell-cells = <1>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               button-reset {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+               };
+
+               button-wifi {
+                       label = "Wi-Fi";
+                       linux,code = <KEY_RFKILL>;
+                       gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+               };
+
+               button-wps {
+                       label = "WPS";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-power {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_POWER;
+                       gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+
+               led-wan-red {
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_WAN;
+                       gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+               };
+
+               led-wps {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_WPS;
+                       gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&gmac0 {
+       nvmem-cells = <&et0macaddr 0>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+       nvmem-cells = <&et0macaddr 1>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+       nvmem-cells = <&et0macaddr 2>;
+       nvmem-cell-names = "mac-address";
+};
+
+&nandcs {
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       reg = <0x00000000 0x00080000>;
+                       label = "boot";
+                       read-only;
+               };
+
+               partition@80000 {
+                       reg = <0x00080000 0x00180000>;
+                       label = "nvram";
+               };
+
+               partition@200000 {
+                       compatible = "brcm,trx";
+                       reg = <0x00200000 0x07e00000>;
+                       label = "firmware";
+               };
+       };
+};
+
+&srab {
+       status = "okay";
+
+       ports {
+               port@0 {
+                       label = "wan";
+               };
+
+               port@1 {
+                       label = "lan1";
+               };
+
+               port@2 {
+                       label = "lan2";
+               };
+
+               port@3 {
+                       label = "lan3";
+               };
+
+               port@4 {
+                       label = "lan4";
+               };
+       };
+};
+
+&usb2 {
+       vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3_phy {
+       status = "okay";
+};
index 5f089307cd8c19f8f02f41d3e3f099ad1c6bd1a7..1655ac95769c0895e826058fab3afd50b34097a9 100644 (file)
 
        nvram@1c080000 {
                et0macaddr: et0macaddr {
+                       #nvmem-cell-cells = <1>;
                };
        };
 };
 
 &gmac0 {
-       nvmem-cells = <&et0macaddr>;
+       nvmem-cells = <&et0macaddr 0>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+       nvmem-cells = <&et0macaddr 1>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+       nvmem-cells = <&et0macaddr 2>;
        nvmem-cell-names = "mac-address";
 };
index 09cefce27fb10786c4f8a4b7475b130fed9edfc9..2cfaaabc7a6a827c03b50be097627d972141ab40 100644 (file)
@@ -6,15 +6,13 @@
 #include "bcm47094.dtsi"
 #include "bcm5301x-nand-cs0-bch8.dtsi"
 
-/ {
-       chosen {
-               bootargs = "earlycon";
-       };
+#include <dt-bindings/leds/common.h>
 
+/ {
        memory@0 {
-               device_type = "memory";
                reg = <0x00000000 0x08000000>,
                      <0x88000000 0x18000000>;
+               device_type = "memory";
        };
 
        nvram@1c080000 {
                reg = <0x1c080000 0x00180000>;
        };
 
-       leds {
-               compatible = "gpio-leds";
+       gpio-keys {
+               compatible = "gpio-keys";
 
-               led-power {
-                       label = "white:power";
-                       gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
-                       linux,default-trigger = "default-on";
+               button-led {
+                       label = "Backlight";
+                       linux,code = <KEY_BRIGHTNESS_ZERO>;
+                       gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
                };
 
-               led-wan-red {
-                       label = "red:wan";
-                       gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+               button-reset {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+               };
+
+               button-wifi {
+                       label = "Wi-Fi";
+                       linux,code = <KEY_RFKILL>;
+                       gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
                };
 
+               button-wps {
+                       label = "WPS";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
                led-lan {
-                       label = "white:lan";
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_LAN;
                        gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
                };
 
+               led-power {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_POWER;
+                       gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+
                led-usb2 {
-                       label = "white:usb2";
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_USB;
+                       function-enumerator = <1>;
                        gpios = <&chipcommon 16 GPIO_ACTIVE_LOW>;
                        trigger-sources = <&ehci_port2>;
                        linux,default-trigger = "usbport";
                };
 
                led-usb3 {
-                       label = "white:usb3";
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_USB;
+                       function-enumerator = <2>;
                        gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
                        trigger-sources = <&ehci_port1>, <&xhci_port1>;
                        linux,default-trigger = "usbport";
                };
 
+               led-wan-red {
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_WAN;
+                       gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+               };
+
                led-wps {
-                       label = "white:wps";
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_WPS;
                        gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
                };
        };
+};
 
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               button-wps {
-                       label = "WPS";
-                       linux,code = <KEY_WPS_BUTTON>;
-                       gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
-               };
+&nandcs {
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
 
-               button-reset {
-                       label = "Reset";
-                       linux,code = <KEY_RESTART>;
-                       gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+               partition@0 {
+                       reg = <0x00000000 0x00080000>;
+                       label = "boot";
+                       read-only;
                };
 
-               button-wifi {
-                       label = "Wi-Fi";
-                       linux,code = <KEY_RFKILL>;
-                       gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+               partition@80000 {
+                       reg = <0x00080000 0x00180000>;
+                       label = "nvram";
                };
 
-               button-led {
-                       label = "Backlight";
-                       linux,code = <KEY_BRIGHTNESS_ZERO>;
-                       gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+               partition@200000 {
+                       compatible = "brcm,trx";
+                       reg = <0x00200000 0x07e00000>;
+                       label = "firmware";
                };
        };
 };
 
 &srab {
-       compatible = "brcm,bcm53012-srab", "brcm,bcm5301x-srab";
        status = "okay";
 
        ports {
 &usb3_phy {
        status = "okay";
 };
-
-&nandcs {
-       partitions {
-               compatible = "fixed-partitions";
-               #address-cells = <1>;
-               #size-cells = <1>;
-
-               partition@0 {
-                       label = "boot";
-                       reg = <0x00000000 0x00080000>;
-                       read-only;
-               };
-
-               partition@80000 {
-                       label = "nvram";
-                       reg = <0x00080000 0x00180000>;
-               };
-
-               partition@200000 {
-                       label = "firmware";
-                       reg = <0x00200000 0x07e00000>;
-                       compatible = "brcm,trx";
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts b/arch/arm/boot/dts/broadcom/bcm47094-asus-rt-ac5300.dts
new file mode 100644 (file)
index 0000000..6c666dc
--- /dev/null
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Author: Tom Brautaset <tbrautaset@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "bcm47094.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+#include <dt-bindings/leds/common.h>
+
+/ {
+       compatible = "asus,rt-ac5300", "brcm,bcm47094", "brcm,bcm4708";
+       model = "ASUS RT-AC5300";
+
+       memory@0 {
+               reg = <0x00000000 0x08000000>,
+                     <0x88000000 0x18000000>;
+               device_type = "memory";
+       };
+
+       nvram@1c080000 {
+               compatible = "brcm,nvram";
+               reg = <0x1c080000 0x00180000>;
+
+               et1macaddr: et1macaddr {
+                       #nvmem-cell-cells = <1>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               button-reset {
+                       label = "Reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&chipcommon 11 GPIO_ACTIVE_LOW>;
+               };
+
+               button-wifi {
+                       label = "Wi-Fi";
+                       linux,code = <KEY_RFKILL>;
+                       gpios = <&chipcommon 20 GPIO_ACTIVE_LOW>;
+               };
+
+               button-wps {
+                       label = "WPS";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-lan {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_LAN;
+                       gpios = <&chipcommon 21 GPIO_ACTIVE_LOW>;
+               };
+
+               led-power {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_POWER;
+                       gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "default-on";
+               };
+
+               led-wan-red {
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_WAN;
+                       gpios = <&chipcommon 5 GPIO_ACTIVE_HIGH>;
+               };
+
+               led-wps {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_WPS;
+                       gpios = <&chipcommon 19 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&gmac0 {
+       nvmem-cells = <&et1macaddr 0>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac1 {
+       nvmem-cells = <&et1macaddr 1>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gmac2 {
+       nvmem-cells = <&et1macaddr 2>;
+       nvmem-cell-names = "mac-address";
+};
+
+&nandcs {
+       partitions {
+               compatible = "fixed-partitions";
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       reg = <0x00000000 0x00080000>;
+                       label = "boot";
+                       read-only;
+               };
+
+               partition@80000 {
+                       reg = <0x00080000 0x00180000>;
+                       label = "nvram";
+               };
+
+               partition@200000 {
+                       compatible = "brcm,trx";
+                       reg = <0x00200000 0x07e00000>;
+                       label = "firmware";
+               };
+       };
+};
+
+&srab {
+       status = "okay";
+
+       ports {
+               port@0 {
+                       label = "lan4";
+               };
+
+               port@1 {
+                       label = "lan3";
+               };
+
+               port@2 {
+                       label = "lan2";
+               };
+
+               port@3 {
+                       label = "lan1";
+               };
+
+               port@4 {
+                       label = "wan";
+               };
+       };
+};
+
+&usb2 {
+       vcc-gpio = <&chipcommon 9 GPIO_ACTIVE_HIGH>;
+};
+
+&usb3_phy {
+       status = "okay";
+};
index fd344b55087e29f4fc21612044965f65840dac27..a197f447fd97f8704235e629753156ec386f698e 100644 (file)
 
        nvram@1c080000 {
                et1macaddr: et1macaddr {
+                       #nvmem-cell-cells = <1>;
                };
        };
 
        switch {
                compatible = "realtek,rtl8365mb";
-               /* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
                mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
                mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
                reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
                realtek,disable-leds;
                dsa,member = <1 0>;
 
+               mdio {
+                       compatible = "realtek,smi-mdio";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       ethphy0: ethernet-phy@0 {
+                               reg = <0>;
+                       };
+
+                       ethphy1: ethernet-phy@1 {
+                               reg = <1>;
+                       };
+
+                       ethphy2: ethernet-phy@2 {
+                               reg = <2>;
+                       };
+
+                       ethphy3: ethernet-phy@3 {
+                               reg = <3>;
+                       };
+               };
+
                ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
                                };
                        };
                };
+       };
+};
 
-               mdio {
-                       compatible = "realtek,smi-mdio";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       ethphy0: ethernet-phy@0 {
-                               reg = <0>;
-                       };
-
-                       ethphy1: ethernet-phy@1 {
-                               reg = <1>;
-                       };
+&gmac0 {
+       status = "disabled";
+};
 
-                       ethphy2: ethernet-phy@2 {
-                               reg = <2>;
-                       };
+&gmac1 {
+       nvmem-cells = <&et1macaddr 0>;
+       nvmem-cell-names = "mac-address";
+};
 
-                       ethphy3: ethernet-phy@3 {
-                               reg = <3>;
-                       };
-               };
-       };
+&gmac2 {
+       nvmem-cells = <&et1macaddr 1>;
+       nvmem-cell-names = "mac-address";
 };
 
 &srab {
                };
        };
 };
-
-&gmac0 {
-       status = "disabled";
-};
-
-&gmac1 {
-       nvmem-cells = <&et1macaddr>;
-       nvmem-cell-names = "mac-address";
-};
index 8c1d5c9fa4831d457a8bedc88132623630ab53e2..2ff7be8f1382bf0bdf015db1fc8b3a5d1195452c 100644 (file)
 
        tegra_ac97: ac97@70002000 {
                status = "okay";
-               nvidia,codec-reset-gpio =
+               nvidia,codec-reset-gpios =
                        <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
-               nvidia,codec-sync-gpio =
+               nvidia,codec-sync-gpios =
                        <&gpio TEGRA_GPIO(P, 0) GPIO_ACTIVE_HIGH>;
        };
 
index afb922bd79a713c39a32a76ac9188d5d900f8122..1408e1e007596e6ce5fda3620e1c67c64b8037c4 100644 (file)
                                        0x00000000 0x00000000 0x00000000 0x00000000>;
                        };
                };
+
+               emc-tables@1 {
+                       nvidia,ram-code = <0x1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+
+                       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>;
+                       };
+               };
        };
 
        usb@c5000000 {
index 4052cad859fa9f2928ae99edcde3cbc2480cdb4b..231c0d73a53ea6f6fe76f9d3c1a2d9d68e8b3fec 100644 (file)
@@ -349,12 +349,15 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ull-phytec-segin-lc-rdk-nand.dtb \
        imx6ull-phytec-tauri-emmc.dtb \
        imx6ull-phytec-tauri-nand.dtb \
+       imx6ull-seeed-npi-dev-board-emmc.dtb \
+       imx6ull-seeed-npi-dev-board-nand.dtb \
        imx6ull-tarragon-master.dtb \
        imx6ull-tarragon-micro.dtb \
        imx6ull-tarragon-slave.dtb \
        imx6ull-tarragon-slavext.dtb \
        imx6ull-tqma6ull2-mba6ulx.dtb \
        imx6ull-tqma6ull2l-mba6ulx.dtb \
+       imx6ull-uti260b.dtb \
        imx6ulz-14x14-evk.dtb \
        imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
index dd03e3860f97f901524570a89552adee135accce..13756d39fb7b9168706f23b9df6cb10026d43b6e 100644 (file)
                compatible = "ricoh,rc5t619";
                reg = <0x32>;
                interrupt-parent = <&gpio5>;
-               interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+               interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
                system-power-controller;
 
                regulators {
index 4e1bf080eaca012ae0d1f9e6e74696eaea41da28..dcc3c9d488a8835303069c57855437bea1df5eb5 100644 (file)
                compatible = "ricoh,rc5t619";
                reg = <0x32>;
                interrupt-parent = <&gpio4>;
-               interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
+               interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
                system-power-controller;
 
                regulators {
index abc9233c5a1b1a8c02c911f58d4c5df22a152d2e..31b3fc972abbfc585c1c65eb10e006c89561dce2 100644 (file)
                device_type = "memory";
                reg = <0xa0000000 0x08000000>; /* 128MB */
        };
+
+       usbotgphy: usbotgphy {
+               compatible = "usb-nop-xceiv";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbotgphy>;
+               reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>;
+               #phy-cells = <0>;
+       };
+
+       usbh2phy: usbh2phy {
+               compatible = "usb-nop-xceiv";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usbh2phy>;
+               reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>;
+               #phy-cells = <0>;
+       };
 };
 
 &cspi1 {
                                MX27_PAD_NFWE_B__NFWE_B 0x0
                        >;
                };
+
+               pinctrl_usbotgphy: usbotgphygrp {
+                       fsl,pins = <
+                               MX27_PAD_USBH1_RCV__GPIO2_25            0x1 /* reset gpio */
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX27_PAD_USBOTG_CLK__USBOTG_CLK         0x0
+                               MX27_PAD_USBOTG_DIR__USBOTG_DIR         0x0
+                               MX27_PAD_USBOTG_NXT__USBOTG_NXT         0x0
+                               MX27_PAD_USBOTG_STP__USBOTG_STP         0x0
+                               MX27_PAD_USBOTG_DATA0__USBOTG_DATA0     0x0
+                               MX27_PAD_USBOTG_DATA1__USBOTG_DATA1     0x0
+                               MX27_PAD_USBOTG_DATA2__USBOTG_DATA2     0x0
+                               MX27_PAD_USBOTG_DATA3__USBOTG_DATA3     0x0
+                               MX27_PAD_USBOTG_DATA4__USBOTG_DATA4     0x0
+                               MX27_PAD_USBOTG_DATA5__USBOTG_DATA5     0x0
+                               MX27_PAD_USBOTG_DATA6__USBOTG_DATA6     0x0
+                               MX27_PAD_USBOTG_DATA7__USBOTG_DATA7     0x0
+                       >;
+               };
+
+               pinctrl_usbh2phy: usbh2phygrp {
+                       fsl,pins = <
+                               MX27_PAD_USBH1_SUSP__GPIO2_22           0x0 /* reset gpio */
+                       >;
+               };
+
+               pinctrl_usbh2: usbh2grp {
+                       fsl,pins = <
+                               MX27_PAD_USBH2_CLK__USBH2_CLK           0x0
+                               MX27_PAD_USBH2_DIR__USBH2_DIR           0x0
+                               MX27_PAD_USBH2_NXT__USBH2_NXT           0x0
+                               MX27_PAD_USBH2_STP__USBH2_STP           0x0
+                               MX27_PAD_CSPI2_SCLK__USBH2_DATA0        0x0
+                               MX27_PAD_CSPI2_MOSI__USBH2_DATA1        0x0
+                               MX27_PAD_CSPI2_MISO__USBH2_DATA2        0x0
+                               MX27_PAD_CSPI2_SS1__USBH2_DATA3         0x0
+                               MX27_PAD_CSPI2_SS2__USBH2_DATA4         0x0
+                               MX27_PAD_CSPI1_SS2__USBH2_DATA5         0x0
+                               MX27_PAD_CSPI2_SS0__USBH2_DATA6         0x0
+                               MX27_PAD_USBH2_DATA7__USBH2_DATA7       0x0
+                       >;
+               };
        };
 };
 
        nand-on-flash-bbt;
        status = "okay";
 };
+
+&usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       phy_type = "ulpi";
+       phys = <&usbotgphy>;
+       status = "okay";
+};
+
+&usbh2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbh2>;
+       phy_type = "ulpi";
+       phys = <&usbh2phy>;
+       status = "okay";
+};
index f7408722d68ab2332f407112bdaf1b942f34cf55..2bd0761c7e900fc69228b7e30b11c6d3dfe17a82 100644 (file)
@@ -45,7 +45,7 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 78770>;
+               pwms = <&pwm1 0 78770 0>;
                brightness-levels = <0 150 200 255>;
                default-brightness-level = <1>;
                power-supply = <&backlight_reg>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm_backlight>;
        status = "okay";
index 0e7f071fd10e2dba7adcd30f1fec8112456bb7a6..f6f1163666434c78276f6f36caa99e68892b60cc 100644 (file)
@@ -13,7 +13,7 @@
 
        backlight_lcd: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm2 0 50000>;
+               pwms = <&pwm2 0 50000 0>;
                power-supply = <&reg_backlight>;
                brightness-levels = <0 24 28 32 36
                                     40 44 48 52 56
index 4508f34139a061aa0a4ce48ccffcc7b2b5da1d9d..ae5f87b8612d485b77248de913446249bb8b9b50 100644 (file)
@@ -13,7 +13,7 @@
                compatible = "pwm-beeper";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_buzzer>;
-               pwms = <&pwm1 0 500000>;
+               pwms = <&pwm1 0 500000 0>;
        };
 
        gpio-buttons {
        >;
 };
 
-&pwm1 {
-       #pwm-cells = <2>;
-};
-
-&pwm2 {
-       #pwm-cells = <2>;
-};
-
 &uart1 {
        status = "okay";
 };
index c323b4dbe9f0adf26b46738d94aea3ce2d2455e6..1353d985969cbb2b28e45475de7560df5efd9e6b 100644 (file)
@@ -41,7 +41,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 3000>;
+               pwms = <&pwm1 0 3000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                power-supply = <&reg_backlight>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 6a37616cef1c2d6bff3a3fe6710f119013f810cf..2117de872703bfdf730f1eacedc653dcaaf8650c 100644 (file)
@@ -17,7 +17,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm2 0 50000>;
+               pwms = <&pwm2 0 50000 0>;
                brightness-levels = <0 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100>;
                default-brightness-level = <10>;
                enable-gpios = <&gpio7 7 0>;
index 70c4a4852256c4ef2321e25b878eb3b01e2780df..e939acc1c88b7c17a5bdaf5a934769f79e5ea8b3 100644 (file)
 
        pwm_bl: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm2 0 50000>;
+               pwms = <&pwm2 0 50000 0>;
                brightness-levels = <0 2 5 7 10 12 15 17 20 22 25 28 30 33 35
                                     38 40 43 45 48 51 53 56 58 61 63 66 68 71
                                     73 76 79 81 84 86 89 91 94 96 99 102 104
 
                led-1 {
                        label = "alarm-brightness";
-                       pwms = <&pwm1 0 100000>;
+                       pwms = <&pwm1 0 100000 0>;
                        max-brightness = <255>;
                };
        };
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
index 294811bfc8d2e0aa869877e2b784c8cdff73c34f..b2d7271d1d24cc4e3aebf206569725411e040913 100644 (file)
        };
 };
 
-&pwm1 {
-       #pwm-cells = <2>;
-};
-
-&pwm2 {
-       #pwm-cells = <2>;
-};
-
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1>;
index cc861a43eb580734c5b7118fca0caa950c09575c..a5ac79346854264fc2daa561a0c93fb1ce0ae591 100644 (file)
@@ -14,7 +14,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                enable-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
@@ -79,6 +79,5 @@
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        status = "okay";
 };
index b6cb78870cd54b76e1eaa6d006cc4de77564b6ee..5a25bdbbeb68711c4bf70ac8aab3e143bae79aed 100644 (file)
@@ -49,7 +49,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 3000>;
+               pwms = <&pwm3 0 3000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                pinctrl-names = "default";
@@ -69,6 +69,5 @@
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        status = "okay";
 };
index 028951955bdee703ab42a56bf197292241df6b9c..72ee236d2f5e8b5fadf6588a5506c39a99d7b7aa 100644 (file)
@@ -21,7 +21,7 @@
 
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 25000>; /* 25000ns -> 40kHz */
+               pwms = <&pwm3 0 25000 0>; /* 25000ns -> 40kHz */
                brightness-levels = <0 4 8 16 32 64 128 160 192 224 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
index f266f1b7e0cfc1b7e28572993c3b36759d227d50..09d9ca0cb3324384fb6fa6fbf817d59bf1bfae4f 100644 (file)
@@ -55,7 +55,7 @@
                compatible = "pwm-backlight";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_display>;
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <  0   1   2   3   4   5   6   7   8   9
                                      10  11  12  13  14  15  16  17  18  19
                                      20  21  22  23  24  25  26  27  28  29
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 02648806c2750861df3d0c61e40d28d3b5508de9..d3f14b4d3b51e19a5bdf52f9d99da4b314da7811 100644 (file)
@@ -36,7 +36,7 @@
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 200000>;
+               pwms = <&pwm1 0 200000 0>;
                brightness-levels = <0 61 499 1706 4079 8022 13938 22237 33328 47623 65535>;
                num-interpolated-steps = <10>;
                default-brightness-level = <60>;
                        color = <LED_COLOR_ID_RED>;
                        max-brightness = <248>;
                        default-state = "off";
-                       pwms = <&pwm2 0 500000>;
+                       pwms = <&pwm2 0 500000 0>;
                };
 
                led_white: led-1 {
                        color = <LED_COLOR_ID_WHITE>;
                        max-brightness = <248>;
                        default-state = "off";
-                       pwms = <&pwm3 0 500000>;
+                       pwms = <&pwm3 0 500000 0>;
                        linux,default-trigger = "heartbeat";
                };
        };
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 091903f53a56097c40f103600e5ddc2bdabb923c..c425d427663d0624646dc55c38a596ba78f6ce04 100644 (file)
@@ -15,7 +15,7 @@
 / {
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 255>;
                num-interpolated-steps = <255>;
                default-brightness-level = <250>;
@@ -23,7 +23,7 @@
 
        beeper {
                compatible = "pwm-beeper";
-               pwms = <&pwm2 0 500000>;
+               pwms = <&pwm2 0 500000 0>;
        };
 
        lcd_display: display {
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
index a7d5a68110fcf723113ea4144ac8d454bbf5b042..d392b5bd2eea8375711995baa433735e1998b621 100644 (file)
@@ -67,7 +67,7 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 10000000>;
+               pwms = <&pwm1 0 10000000 0>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_backlight_novena>;
                power-supply = <&reg_lvds_lcd>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
index 46c6b96d80739918765cf2ecfef2d2967fb2cba0..56b77cc0af2be51d8eb6a9b0931d977e1f267670 100644 (file)
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 50000>;
+               pwms = <&pwm1 0 50000 0>;
                brightness-levels = <
                        0  /*1  2  3  4  5  6*/  7  8  9
                        10 11 12 13 14 15 16 17 18 19
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 3508a2cd928a1af8fc31c2a88d51eb83e94817ca..a7d5693c5ab75257ed916578a52036b82739a3d6 100644 (file)
@@ -22,7 +22,7 @@
                compatible = "pwm-backlight";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_backlight>;
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 16 64 255>;
                num-interpolated-steps = <16>;
                default-brightness-level = <1>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 2290c1237634d9d77e8e99ead95648e3a6db3ac2..0225a621ec7a9e697ba95cf0617513156f8c521f 100644 (file)
@@ -18,7 +18,7 @@
 
        backlight_lvds: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm2 0 50000>;
+               pwms = <&pwm2 0 50000 0>;
                brightness-levels = <0 4 8 16 32 64 128 248>;
                default-brightness-level = <7>;
                status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
index 338d292553ad5461530ba51ac312a370bdaa3297..3a46ade3b6bd93ba9cc54861d88791eef9e2ae76 100644 (file)
@@ -13,7 +13,7 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 191000>;
+               pwms = <&pwm3 0 191000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <0>;
                power-supply = <&reg_5v>;
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
index db1bc511e71f71fdc1dfaba508dca12727de9e0f..758eaf9d93d2a44c1cc8cb457a82005aabcf4fec 100644 (file)
@@ -46,7 +46,7 @@
 / {
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                enable-gpios = <&gpio6 31 GPIO_ACTIVE_HIGH>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 1e530d892b768dda9146c30df8a48e4cca9e065f..761566ae3cf5c0360db9bbc0a790ebe64b9f318d 100644 (file)
@@ -64,7 +64,7 @@
                        active-low;
                        label = "imx6:red:front";
                        max-brightness = <248>;
-                       pwms = <&pwm1 0 50000>;
+                       pwms = <&pwm1 0 50000 0>;
                };
        };
 
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
index 42b2ba23aefc9e26ddb3a8e0317013e30602fdbe..a308a3584b62571bc5bb3a4012edc5f8d90b636d 100644 (file)
@@ -66,7 +66,7 @@
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_lvds_bl>;
                enable-gpios = <&gpio6 9 GPIO_ACTIVE_HIGH>;
-               pwms = <&pwm1 0 50000>;
+               pwms = <&pwm1 0 50000 0>;
                brightness-levels = <
                        0 4 8 16 32 64 80 96 112
                        128 144 160 176 250
@@ -78,7 +78,7 @@
        pwm_fan: pwm-fan {
                compatible = "pwm-fan";
                #cooling-cells = <2>;
-               pwms = <&pwm4 0 50000>;
+               pwms = <&pwm4 0 50000 0>;
                cooling-levels = <0 64 127 191 255>;
                status = "disabled";
        };
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_rgb_bl>;
                enable-gpios = <&gpio6 8 GPIO_ACTIVE_HIGH>;
-               pwms = <&pwm3 0 5000000>;
+               pwms = <&pwm3 0 5000000 0>;
                brightness-levels = <
                        250 176 160 144 128 112
                        96 80 64 48 32 16 8 1
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        status = "okay";
 };
 
index 535679c27d6f75a29a7b5622346002be9dff320d..48ffb3ee01bdcd02431161980055f1db57759956 100644 (file)
@@ -25,7 +25,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 3e1c572af58267640e660edca5b92a298be10b6d..1eae438fbdaeb518c5b850746929197341416489 100644 (file)
@@ -25,7 +25,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 0ffa0357a6fa60d9629d3864fc6f0f93e6e65684..c2ec8572c8a50c4327e7353589a0b3e036f48326 100644 (file)
@@ -26,7 +26,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default", "state_dio";
        pinctrl-0 = <&pinctrl_pwm4_backlight>;
        pinctrl-1 = <&pinctrl_pwm4_dio>;
index 46cf4080fec384fc98413a48e59e3d52a1db6a62..7cee983da669510fe0dc42897ffff9ad8b38b861 100644 (file)
@@ -66,7 +66,7 @@
 
        backlight-display {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <
                        0  1  2  3  4  5  6  7  8  9
                        10 11 12 13 14 15 16 17 18 19
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index a74cde05015894c08543ee34eb380002f5355d6a..fbc704c064b6dee10d7f45f04ced4bf4b564d242 100644 (file)
@@ -56,7 +56,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <
                        0  1  2  3  4  5  6  7  8  9
                        10 11 12 13 14 15 16 17 18 19
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 1e723807ab4c2424b6259fec11201847f231a33f..070506279186bbe75e634fa1febb73dd628b3be2 100644 (file)
@@ -70,7 +70,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index efe11524b885db38ffa295d0e4465611114702bf..9975b6ee433d1daf4ed24bf2b91f167fbaa398ff 100644 (file)
@@ -20,7 +20,7 @@
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 100000>;
+               pwms = <&pwm3 0 100000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
        };
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
index 4d2abcd44eff2455a836e7237b83bce01ec8ed6c..60aa1e947f62f8623af823850446437b8a2e08bf 100644 (file)
                reg = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
+               vdd-supply = <&reg_mba6_3p3v>;
 
                ethernet@1 {
                        compatible = "usb424,9e00";
 
        pinctrl_hog: hoggrp {
                fsl,pins = <
-                       MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x0001b099
-
                        MX6QDL_PAD_ENET_RXD1__GPIO1_IO26 0x0001b099
                        MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x0001b099
                        MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x0001b099
index f2542d725ce7db45b4a2e9ff19dea024745c2f52..a30cf0d06206f3294262446012dc98999a606873 100644 (file)
 
        backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 
        backlight_lvds0: backlight-lvds0 {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 32a110a35b0253c9643ce6902a331ed785350b2b..33174febf410b967c3ac47307e954507731da282 100644 (file)
 
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 
        backlight_lvds0: backlight-lvds0 {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 
        backlight_lvds1: backlight-lvds1 {
                compatible = "pwm-backlight";
-               pwms = <&pwm2 0 5000000>;
+               pwms = <&pwm2 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 414196b759910ad55c4154cd59fa6881155a7e33..8e64314fa8b2a6f69e10fa0577e49ef6bb931345 100644 (file)
@@ -17,7 +17,7 @@
 
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
@@ -26,7 +26,7 @@
 
        backlight_lvds0: backlight-lvds0 {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index f278b14911ced270f3e993e2c8addb2f1dd7fc52..121177273dd007bda2c1f11932f479d472453868 100644 (file)
 
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 1ca4d219609f69fa71d3b514b25b1cd82b18f019..0b4c09b09c03dcc2a8628a8eb449143e32cbf8fe 100644 (file)
@@ -15,7 +15,7 @@
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_backlight>;
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                status = "okay";
        };
 
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 68e97180d33e38831865b866e861001bca2e4a3d..6656e2e762a1a4e32e6d91d77a38ff9ada98628d 100644 (file)
        };
 
        sound-spdif {
-               compatible = "fsl,imx-audio-spdif",
-                          "fsl,imx-sabreauto-spdif";
+               compatible = "fsl,imx-sabreauto-spdif",
+                            "fsl,imx-audio-spdif";
                model = "imx-spdif";
                spdif-controller = <&spdif>;
                spdif-in;
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 5000000>;
+               pwms = <&pwm3 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                status = "okay";
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
index 84c8a9531e181596bc800b2aa94d6c68edf54519..9c502bf77d0bf05e635197f74beef2e5c8141e95 100644 (file)
@@ -99,7 +99,7 @@
                #clock-cells = <0>;
                clock-frequency = <22000000>;
                clock-output-names = "mipi_pwm3";
-               pwms = <&pwm3 0 45>; /* 1 / 45 ns = 22 MHz */
+               pwms = <&pwm3 0 45 0>; /* 1 / 45 ns = 22 MHz */
                status = "okay";
        };
 
 
        backlight_lcd: backlight-lcd {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_3p3v>;
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
index 4fe58764b929aee760f60d78a8ad7a6998b57752..8f4f5fba68cc5f4ff8af1465e618905ba34c5710 100644 (file)
 
        backlight_lvds: backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                status = "okay";
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 02e6d36e85fa82c60bef34a1644277a767108d0e..6823a639ed2fc25db1e153178ae376733d7c6472 100644 (file)
@@ -83,7 +83,7 @@
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <4>;
                power-supply = <&reg_3p3v>;
-               pwms = <&pwm1 0 10000>;
+               pwms = <&pwm1 0 10000 0>;
        };
 
        reg_3p3v: regulator-3p3v {
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index d59d5d0e1d19ea6aff4c54ff26178140ff7dbc51..6ab71a729fd85d0b0b6dbfbd810692b1a0e05ec6 100644 (file)
 &pwm2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
-       #pwm-cells = <2>;
        status = "okay";
 };
 
index 647ba5e623ddfa2aae04339576f2746e63993957..14272b42f9a1aea0031dc33e4667c523e2ebdeda 100644 (file)
                };
        };
 
-       reg_usb_h1_vbus: regulator-usb-h1-vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usb_h1_vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               enable-active-high;
-               startup-delay-us = <2>; /* USB2415 requires a POR of 1 us minimum */
-               gpio = <&gpio7 12 0>;
-       };
-
        reg_panel: regulator-panel {
                compatible = "regulator-fixed";
                regulator-name = "lcd_panel";
 &usbh1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usbh>;
-       vbus-supply = <&reg_usb_h1_vbus>;
-       clocks = <&clks IMX6QDL_CLK_CKO>;
-       status = "disabled";
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       usb-port@1 {
+               compatible = "usb424,2514";
+               reg = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&clks IMX6QDL_CLK_CKO>;
+               reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+       };
 };
 
 &usbotg {
index 8431b8a994f4c19a2e696019ab4dfaab62af5676..d2200c9db25aec90dbd348dedee4bfef47eb3ee7 100644 (file)
                                        reg = <0x02024000 0x4000>;
                                        interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6QDL_CLK_ESAI_IPG>,
-                                                <&clks IMX6QDL_CLK_ESAI_MEM>,
                                                 <&clks IMX6QDL_CLK_ESAI_EXTAL>,
                                                 <&clks IMX6QDL_CLK_ESAI_IPG>,
                                                 <&clks IMX6QDL_CLK_SPBA>;
-                                       clock-names = "core", "mem", "extal", "fsys", "spba";
+                                       clock-names = "core", "extal", "fsys", "spba";
                                        dmas = <&sdma 23 21 0>, <&sdma 24 21 0>;
                                        dma-names = "rx", "tx";
                                        status = "disabled";
index 239bc6dfc5846475b17ccbf080030959c43eddf2..31eee0419af71c628c1b2849fa944e30df891af8 100644 (file)
@@ -23,7 +23,7 @@
 
        backlight_display: backlight_display {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
        };
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
-       status = "okay";
 };
 
 &reg_vdd1p1 {
index 5636fb3661e8a4e345e74767e329e403d2a58c9e..03d6965f014957a9ac7a9799554620fd4ae5e392 100644 (file)
                pinctrl-0 = <&pinctrl_zforce>;
                reg = <0x50>;
                interrupt-parent = <&gpio5>;
-               interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+               interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
                vdd-supply = <&ldo1_reg>;
                reset-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
                touchscreen-size-x = <1072>;
                pinctrl-0 = <&pinctrl_ricoh_gpio>;
                reg = <0x32>;
                interrupt-parent = <&gpio5>;
-               interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+               interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
                system-power-controller;
 
                regulators {
index e3e9b0ec4f734af2f660d917f64113a22bceeb9b..febc2dd9967de69e109bbd3d5d92217b6cbea13f 100644 (file)
@@ -26,7 +26,7 @@
 
        backlight_display: backlight-display {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                status = "okay";
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
-       status = "okay";
 };
 
 &snvs_poweroff {
index 3659fd5ecfa620e665edf570dd9d2b8c0f24bc09..ddeb5b37fb78b92e8b56fd8b1714d30f1760baa1 100644 (file)
                                clocks = <&clks IMX6SLL_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
-                               fsl,anatop = <&anatop>;
                                ahb-burst-config = <0x0>;
                                tx-burst-size-dword = <0x10>;
                                rx-burst-size-dword = <0x10>;
index cd9cbc9ccc9e33cc7062ccb719ed70fcce16b101..1c1515a854c813c182390dc9f94b31fbd3f05bee 100644 (file)
@@ -18,7 +18,7 @@
 
        backlight-lvds {
                compatible = "pwm-backlight";
-               pwms = <&pwm4 0 5000000>;
+               pwms = <&pwm4 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                power-supply = <&reg_3p3v>;
@@ -83,7 +83,7 @@
        sound {
                compatible = "fsl,imx-audio-sgtl5000";
                model = "imx6sx-nitrogen6sx-sgtl5000";
-               cpu-dai = <&ssi1>;
+               ssi-controller = <&ssi1>;
                audio-codec = <&codec>;
                audio-routing =
                        "MIC_IN", "Mic Jack",
 };
 
 &pwm4 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm4>;
-       status = "okay";
 };
 
 &ssi1 {
index c6e85e4a0883e0f233ba84dc0fe88357b2560d0e..7d4170c2773284d09ca29fa162f447844e06fef0 100644 (file)
@@ -23,7 +23,7 @@
 
        backlight_display: backlight-display {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 5000000>;
+               pwms = <&pwm3 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
        };
        };
 
        sound-spdif {
-               compatible = "fsl,imx-audio-spdif",
-                          "fsl,imx6sx-sdb-spdif";
+               compatible = "fsl,imx6sx-sdb-spdif",
+                            "fsl,imx-audio-spdif";
                model = "imx-spdif";
                spdif-controller = <&spdif>;
                spdif-out;
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
-       status = "okay";
 };
 
 &snvs_poweroff {
index bfcd8f7d86dde104035a9f4659c214782c847260..f999eb2443739ccda99c09ea5c3bb2ae08fa37bc 100644 (file)
                led-1 {
                        label = "red";
                        max-brightness = <255>;
-                       pwms = <&pwm6 0 50000>;
+                       pwms = <&pwm6 0 50000 0>;
                };
 
                led-2 {
                        label = "green";
                        max-brightness = <255>;
-                       pwms = <&pwm2 0 50000>;
+                       pwms = <&pwm2 0 50000 0>;
                };
 
                led-3 {
                        label = "blue";
                        max-brightness = <255>;
-                       pwms = <&pwm1 0 50000>;
+                       pwms = <&pwm1 0 50000 0>;
                };
        };
 };
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
-       status = "okay";
 };
 
 &pwm2 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm2>;
-       status = "okay";
 };
 
 &pwm6 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm6>;
-       status = "okay";
 };
 
 &reg_arm {
index 0de359d62a472f9942ffb1de8c844400dbd035ba..b386448486df80a033efbad38c37a4dd04ee1caa 100644 (file)
                                };
 
                                esai: esai@2024000 {
-                                       compatible = "fsl,imx6sx-esai", "fsl,imx35-esai";
+                                       compatible = "fsl,imx35-esai";
                                        reg = <0x02024000 0x4000>;
                                        interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
                                        clocks = <&clks IMX6SX_CLK_ESAI_IPG>,
-                                                <&clks IMX6SX_CLK_ESAI_MEM>,
                                                 <&clks IMX6SX_CLK_ESAI_EXTAL>,
                                                 <&clks IMX6SX_CLK_ESAI_IPG>,
                                                 <&clks IMX6SX_CLK_SPBA>;
-                                       clock-names = "core", "mem", "extal",
+                                       clock-names = "core", "extal",
                                                      "fsys", "spba";
                                        dmas = <&sdma 23 21 0>,
                                               <&sdma 24 21 0>;
                                clocks = <&clks IMX6SX_CLK_USBOH3>;
                                fsl,usbphy = <&usbphy1>;
                                fsl,usbmisc = <&usbmisc 0>;
-                               fsl,anatop = <&anatop>;
                                ahb-burst-config = <0x0>;
                                tx-burst-size-dword = <0x10>;
                                rx-burst-size-dword = <0x10>;
                                fsl,usbphy = <&usbphynop1>;
                                fsl,usbmisc = <&usbmisc 2>;
                                phy_type = "hsic";
-                               fsl,anatop = <&anatop>;
                                dr_mode = "host";
                                ahb-burst-config = <0x0>;
                                tx-burst-size-dword = <0x10>;
index f10f0525490b66f413c9fa9a41d08f8a82ae35f2..9cfb99ac9e9daaf5fe7479aee9dc8888909e4bdc 100644 (file)
@@ -16,7 +16,7 @@
 
        backlight_display: backlight-display {
                compatible = "pwm-backlight";
-               pwms = <&pwm1 0 5000000>;
+               pwms = <&pwm1 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                status = "okay";
 };
 
 &pwm1 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm1>;
        status = "okay";
index 1762bc47e18d50f23b96fb3b98c4b40e6a3e887e..ed61ae8524fa2a1445c7df50b2cdb03799b1c141 100644 (file)
@@ -18,7 +18,7 @@
 
        lcd_backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm5 0 50000>;
+               pwms = <&pwm5 0 50000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                status = "okay";
 };
 
 &pwm5 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm5>;
        status = "okay";
index 2ca18f3dad0aa6576398235398047753a79b285b..cdbb8c435cd6aa54036b646a39f3fd7873aec0fb 100644 (file)
@@ -21,7 +21,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm8 0 100000>;
+               pwms = <&pwm8 0 100000 0>;
                brightness-levels = < 0  1  2  3  4  5  6  7  8  9
                                     10 11 12 13 14 15 16 17 18 19
                                     20 21 22 23 24 25 26 27 28 29
 };
 
 &pwm8 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm8>;
        status = "okay";
index af337f18a266ca846be7ae3652a40ff69f507809..be3cacb4fa7abcab1b6b210079b38b4d0cf1df11 100644 (file)
@@ -9,7 +9,7 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 191000>;
+               pwms = <&pwm3 0 191000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <7>;
                power-supply = <&reg_5v>;
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
index 14fc4828ba4ef47b175e14f686aa397a3866263a..ee86c36205f9554dd1c8b5b853df3742ab9ae426 100644 (file)
@@ -20,7 +20,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm8 0 100000>;
+               pwms = <&pwm8 0 100000 0>;
                brightness-levels = < 0  1  2  3  4  5  6  7  8  9
                                     10 11 12 13 14 15 16 17 18 19
                                     20 21 22 23 24 25 26 27 28 29
 };
 
 &pwm8 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm8>;
        status = "okay";
index 0c643706a158be9ea2aff6493a0b0eeff59cf0aa..4e8191a65211330c15f972ba41d8adccba24a5ba 100644 (file)
@@ -14,7 +14,7 @@
 
        backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm7 0 5000000>;
+               pwms = <&pwm7 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                status = "okay";
@@ -41,7 +41,6 @@
 };
 
 &pwm7 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm7>;
        status = "okay";
index 33d5f27285a476d7a3308b4cb7d92a5408a76385..d8f7877349c98fdeb8c211a719c303b978e57cd0 100644 (file)
@@ -35,7 +35,7 @@
 
        pwm-beeper {
                compatible = "pwm-beeper";
-               pwms = <&pwm8 0 5000>;
+               pwms = <&pwm8 0 5000 0>;
        };
 
        reg_3v3: regulator-3v3 {
 };
 
 &pwm8 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm8>;
        status = "okay";
index 07dcecbe485dca41b66f3deef932f750d31f5544..fe307f49b9e56794f538486a90cc0af6cfe3bd5e 100644 (file)
@@ -22,7 +22,7 @@
 
        backlight: backlight {
                compatible = "pwm-backlight";
-               pwms = <&pwm3 0 5000000>;
+               pwms = <&pwm3 0 5000000 0>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
                status = "okay";
 };
 
 &pwm3 {
-       #pwm-cells = <2>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm3>;
        status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-emmc.dts
new file mode 100644 (file)
index 0000000..cfcd878
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-seeed-npi.dtsi"
+#include "imx6ull-seeed-npi-dev-board.dtsi"
+
+/ {
+       model = "Seeed NPi iMX6ULL Dev Board with NAND";
+       compatible = "seeed,imx6ull-seeed-npi-emmc", "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+};
+
+&usdhc2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board-nand.dts
new file mode 100644 (file)
index 0000000..87c9434
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-seeed-npi.dtsi"
+#include "imx6ull-seeed-npi-dev-board.dtsi"
+
+/ {
+       model = "Seeed NPi iMX6ULL Dev Board with NAND";
+       compatible = "seeed,imx6ull-seeed-npi-nand", "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+};
+
+&gpmi {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi-dev-board.dtsi
new file mode 100644 (file)
index 0000000..6bb12e0
--- /dev/null
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       gpio_buttons: gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_button>;
+
+               button-0 {
+                       gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+                       label = "SW2";
+                       linux,code = <KEY_A>;
+                       wakeup-source;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led-blue {
+                       gpios = <&gpio4 19 GPIO_ACTIVE_LOW>;
+                       label = "LED_B";
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+
+               led-green {
+                       gpios = <&gpio4 20 GPIO_ACTIVE_LOW>;
+                       label = "LED_G";
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+
+               led-red {
+                       gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+                       label = "LED_R";
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+
+               led-user {
+                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+                       label = "User";
+                       linux,default-trigger = "heartbeat";
+                       default-state = "on";
+               };
+       };
+
+       reg_5v_sys: regulator-5v-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "5V_SYS";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               vin-supply = <&reg_5v_sys>;
+       };
+
+       reg_3v3_in: regulator-3v3-in {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3_IN";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&reg_5v_sys>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&reg_3v3_in>;
+       };
+
+       reg_sd1_vmmc: regulator-sd1-vmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "3V3_SD";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_vmmc>;
+               enable-active-high;
+               regulator-always-on;
+               vin-supply = <&reg_3v3>;
+       };
+};
+
+&csi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_csi1>;
+       status = "disabled"; /* LED Blue & Green shared */
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy0>;
+       status = "okay";
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet2>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy1>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@2 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <2>;
+                       micrel,led-mode = <1>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
+               };
+
+               ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <1>;
+                       micrel,led-mode = <1>;
+                       clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+                       clock-names = "rmii-ref";
+               };
+       };
+};
+
+&lcdif {
+       pinctrl-0 = <&pinctrl_lcdif>;
+       pinctrl-names = "default";
+       status = "disabled";
+};
+
+&reg_dcdc_3v3 {
+       vin-supply = <&reg_3v3_in>;
+};
+
+&sai2 {
+       assigned-clock-rates = <320000000>;
+       assigned-clocks = <&clks IMX6UL_CLK_PLL3_PFD2>;
+       pinctrl-0 = <&pinctrl_sai2>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&snvs_poweroff {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-0 = <&pinctrl_uart2>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-0 = <&pinctrl_uart3>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb_otg1_id>;
+       dr_mode = "otg";
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       status = "okay";
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_usdhc1_cd>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz &pinctrl_usdhc1_cd>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz &pinctrl_usdhc1_cd>;
+       cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+       no-1-8-v;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_sd1_vmmc>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_button: buttongrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x0b0b0
+               >;
+       };
+
+       pinctrl_csi1: csi1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK        0x1b088
+                       MX6UL_PAD_CSI_VSYNC__CSI_VSYNC          0x1b088
+                       MX6UL_PAD_CSI_HSYNC__CSI_HSYNC          0x1b088
+                       MX6UL_PAD_CSI_DATA00__CSI_DATA02        0x1b088
+                       MX6UL_PAD_CSI_DATA01__CSI_DATA03        0x1b088
+                       MX6UL_PAD_CSI_DATA02__CSI_DATA04        0x1b088
+                       MX6UL_PAD_CSI_DATA03__CSI_DATA05        0x1b088
+                       MX6UL_PAD_CSI_DATA04__CSI_DATA06        0x1b088
+                       MX6UL_PAD_CSI_DATA05__CSI_DATA07        0x1b088
+                       MX6UL_PAD_CSI_DATA06__CSI_DATA08        0x1b088
+                       MX6UL_PAD_CSI_DATA07__CSI_DATA09        0x1b088
+               >;
+       };
+
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b031
+               >;
+       };
+
+       pinctrl_enet2: enet2grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET2_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET2_MDIO        0x1b0b0
+                       MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
+               >;
+       };
+
+       pinctrl_gpio_leds: ledgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0x0b0b0
+                       MX6UL_PAD_CSI_VSYNC__GPIO4_IO19         0x0b0b0
+                       MX6UL_PAD_CSI_HSYNC__GPIO4_IO20         0x0b0b0
+                       MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x0b0b0
+               >;
+       };
+
+       pinctrl_lcdif: lcdif-grp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK            0x79
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE      0x79
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC        0x79
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC        0x79
+                       MX6UL_PAD_LCD_RESET__LCDIF_RESET        0x79
+                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00      0x79
+                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01      0x79
+                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02      0x79
+                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03      0x79
+                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04      0x79
+                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05      0x79
+                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06      0x79
+                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07      0x79
+                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08      0x79
+                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09      0x79
+                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10      0x79
+                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11      0x79
+                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12      0x79
+                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13      0x79
+                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14      0x79
+                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15      0x79
+                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16      0x79
+                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17      0x79
+                       MX6UL_PAD_LCD_DATA18__LCDIF_DATA18      0x79
+                       MX6UL_PAD_LCD_DATA19__LCDIF_DATA19      0x79
+                       MX6UL_PAD_LCD_DATA20__LCDIF_DATA20      0x79
+                       MX6UL_PAD_LCD_DATA21__LCDIF_DATA21      0x79
+                       MX6UL_PAD_LCD_DATA22__LCDIF_DATA22      0x79
+                       MX6UL_PAD_LCD_DATA23__LCDIF_DATA23      0x79
+                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0x79
+               >;
+       };
+
+       pinctrl_reg_vmmc: usdhc1regvmmc {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059
+               >;
+       };
+
+       pinctrl_sai2: sai2-grp {
+               fsl,pins = <
+                       MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA        0x130b0
+                       MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK        0x17088
+                       MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC        0x17088
+                       MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA     0x120b0
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pin = <
+                       MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pin = <
+                       MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX   0x1b0b1
+                       MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS    0x1b0b1
+                       MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pin = <
+                       MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
+                       MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS    0x1b0b1
+                       MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pin = <
+                       MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pin = <
+                       MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usb_otg1_id: usbotg1idgrp {
+               fsl,pin = <
+                       MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID    0x17059
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x170b9
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x100b9
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x170b9
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x170b9
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x170b9
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x170b9
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x170f9
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x100f9
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x170f9
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x170f9
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x170f9
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x170f9
+               >;
+       };
+
+       pinctrl_usdhc1_cd: usdhc1cd {
+               fsl,pins = <
+                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x17059
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-seeed-npi.dtsi
new file mode 100644 (file)
index 0000000..f5ad6b5
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Linumiz
+ * Author: Parthiban <parthiban@linumiz.com>
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Seeed NPi-iMX6ULL Dev Board";
+       compatible = "seeed,imx6ull-seeed-npi", "fsl,imx6ull";
+
+       reg_dcdc_3v3: regulator-dcdc-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "DCDC_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_dram_1v35: regulator-dram-1v35 {
+               compatible = "regulator-fixed";
+               regulator-name = "DRAM_1V35";
+               regulator-min-microvolt = <1350000>;
+               regulator-max-microvolt = <1350000>;
+               regulator-always-on;
+               vin-supply = <&reg_dcdc_3v3>;
+       };
+
+       reg_vdd_arm_soc_in: regulator-vdd-arm-soc-in {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_ARM_SOC_IN";
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1200000>;
+               regulator-always-on;
+               vin-supply = <&reg_dcdc_3v3>;
+       };
+
+       reg_dcdc_1v8: regulator-dcdc-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "DCDC_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               vin-supply = <&reg_dcdc_3v3>;
+       };
+
+       reg_sd1_vqmmc: regulator-sd1-vqmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "NVCC_SD";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_vqmmc>;
+               regulator-always-on;
+               vin-supply = <&reg_dcdc_1v8>;
+       };
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "disabled";
+};
+
+&usdhc1 {
+       vqmmc-supply = <&reg_sd1_vqmmc>;
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       keep-power-in-suspend;
+       status = "disabled";
+};
+
+&iomuxc {
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_DQS__RAWNAND_DQS         0x0b0b1
+                       MX6UL_PAD_NAND_CLE__RAWNAND_CLE         0x0b0b1
+                       MX6UL_PAD_NAND_ALE__RAWNAND_ALE         0x0b0b1
+                       MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B       0x0b0b1
+                       MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x0b000
+                       MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B     0x0b0b1
+                       MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B     0x0b0b1
+                       MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B       0x0b0b1
+                       MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B       0x0b0b1
+                       MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00   0x0b0b1
+                       MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01   0x0b0b1
+                       MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02   0x0b0b1
+                       MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03   0x0b0b1
+                       MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04   0x0b0b1
+                       MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05   0x0b0b1
+                       MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06   0x0b0b1
+                       MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07   0x0b0b1
+               >;
+       };
+
+       pinctrl_reg_vqmmc: usdhc1regvqmmc {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO05__GPIO1_IO05        0x17059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x10069
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x17059
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x17059
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x17059
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x17059
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x17059
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4     0x17059
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5     0x17059
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6     0x17059
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7     0x17059
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100b9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170b9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170b9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170b9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170b9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170b9
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4     0x170b9
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5     0x170b9
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6     0x170b9
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7     0x170b9
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100f9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170f9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170f9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170f9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170f9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170f9
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4     0x170f9
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5     0x170f9
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6     0x170f9
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7     0x170f9
+               >;
+       };
+};
index 67007ce383e3caf21438bb6fbdfbec2f3bb719b3..f9bbd589b66da8e2900d41920b014fad115688f6 100644 (file)
@@ -45,7 +45,7 @@
                interrupts = <19 IRQ_TYPE_EDGE_RISING>;
                spi-cpha;
                spi-cpol;
-               spi-max-frequency = <16000000>;
+               spi-max-frequency = <12000000>;
        };
 };
 
@@ -63,7 +63,7 @@
                interrupts = <9 IRQ_TYPE_EDGE_RISING>;
                spi-cpha;
                spi-cpol;
-               spi-max-frequency = <16000000>;
+               spi-max-frequency = <12000000>;
        };
 };
 
index cee223b5f8e1cf087b7508c8a769907a020147cb..ef06619d7c867c70ee0cdc732c687764d90de18d 100644 (file)
@@ -23,7 +23,7 @@
                interrupts = <19 IRQ_TYPE_EDGE_RISING>;
                spi-cpha;
                spi-cpol;
-               spi-max-frequency = <16000000>;
+               spi-max-frequency = <12000000>;
        };
 };
 
index 7fd53b7a4372329e23bbd94de0bdc23c99f5df1f..83db65bf630fc9b6fc9f4075773fc91599f3eb1a 100644 (file)
@@ -45,7 +45,7 @@
                interrupts = <19 IRQ_TYPE_EDGE_RISING>;
                spi-cpha;
                spi-cpol;
-               spi-max-frequency = <16000000>;
+               spi-max-frequency = <12000000>;
        };
 };
 
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts b/arch/arm/boot/dts/nxp/imx/imx6ull-uti260b.dts
new file mode 100644 (file)
index 0000000..e4576d5
--- /dev/null
@@ -0,0 +1,566 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) 2022-2024 Sebastian Reichel <sre@kernel.org>
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/clock/imx6ul-clock.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       model = "UNI-T UTi260B Thermal Camera";
+       compatible = "uni-t,uti260b", "fsl,imx6ull";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>;
+       };
+
+       panel_backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               enable-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_backlight_enable>;
+               power-supply = <&reg_vsd>;
+               pwms = <&pwm1 0 50000 0>;
+       };
+
+       battery: battery {
+               compatible = "simple-battery";
+               /* generic 26650 battery */
+               device-chemistry = "lithium-ion";
+               charge-full-design-microamp-hours = <5000000>;
+               voltage-max-design-microvolt = <4200000>;
+               voltage-min-design-microvolt = <3300000>;
+       };
+
+       tp5000: charger {
+               compatible = "gpio-charger";
+               charger-type = "usb-sdp";
+               gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_charger_stat1>;
+       };
+
+       fuel-gauge {
+               compatible = "adc-battery";
+               charged-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+               io-channel-names = "voltage";
+               io-channels = <&adc1 7>;
+               monitored-battery = <&battery>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_charger_stat2>;
+               power-supplies = <&tp5000>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_gpio_keys>;
+               autorepeat;
+
+               up-key {
+                       label = "Up";
+                       gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_UP>;
+               };
+
+               down-key {
+                       label = "Down";
+                       gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_DOWN>;
+               };
+
+               left-key {
+                       label = "Left";
+                       gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_LEFT>;
+               };
+
+               right-key {
+                       label = "Right";
+                       gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_RIGHT>;
+               };
+
+               ok-key {
+                       label = "Ok";
+                       gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_ENTER>;
+               };
+
+               return-key {
+                       label = "Return";
+                       gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_ESC>;
+               };
+
+               play-key {
+                       label = "Media";
+                       gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_MEDIA>;
+               };
+
+               trigger-key {
+                       label = "Trigger";
+                       gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+                       linux,code = <BTN_TRIGGER>;
+               };
+
+               power-key {
+                       label = "Power";
+                       gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+               };
+
+               light-key {
+                       label = "Light";
+                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_LIGHTS_TOGGLE>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_led_ctrl>;
+
+               led {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_FLASH;
+                       gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+                       default-state = "off";
+               };
+       };
+
+       poweroff {
+               compatible = "gpio-poweroff";
+               gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_poweroff>;
+       };
+
+       reg_vref: regulator-vref-4v2 {
+               compatible = "regulator-fixed";
+               regulator-name = "VREF_4V2";
+               regulator-min-microvolt = <4200000>;
+               regulator-max-microvolt = <4200000>;
+       };
+
+       reg_vsd: regulator-vsd {
+               compatible = "regulator-fixed";
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&adc1 {
+       #io-channel-cells = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_adc>;
+       vref-supply = <&reg_vref>;
+       status = "okay";
+};
+
+&csi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_csi>;
+       status = "okay";
+
+       port {
+               parallel_from_gc0308: endpoint {
+                       remote-endpoint = <&gc0308_to_parallel>;
+               };
+       };
+};
+
+&ecspi3 {
+       cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_spi3>;
+       status = "okay";
+
+       panel@0 {
+               compatible = "inanbo,t28cp45tn89-v17";
+               reg = <0>;
+               backlight = <&panel_backlight>;
+               power-supply = <&reg_vsd>;
+               spi-cpha;
+               spi-cpol;
+               spi-max-frequency = <1000000>;
+               spi-rx-bus-width = <0>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+};
+
+&gpio1 {
+       ir-reset-hog {
+               gpio-hog;
+               gpios = <3 GPIO_ACTIVE_LOW>;
+               line-name = "ir-reset-gpio";
+               output-low;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_ir_reset>;
+       };
+};
+
+&gpio2 {
+       /* configuring this to output-high results in poweroff */
+       power-en-hog {
+               gpio-hog;
+               gpios = <6 GPIO_ACTIVE_HIGH>;
+               line-name = "power-en-gpio";
+               output-low;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_poweroff2>;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_i2c1>;
+       status = "okay";
+
+       camera@21 {
+               compatible = "galaxycore,gc0308";
+               reg = <0x21>;
+               clocks = <&clks IMX6UL_CLK_CSI>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&mux_gc0308>;
+               powerdown-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+               vdd28-supply = <&reg_vsd>;
+
+               port {
+                       gc0308_to_parallel: endpoint {
+                               remote-endpoint = <&parallel_from_gc0308>;
+                               bus-width = <8>;
+                               data-shift = <2>; /* lines 9:2 are used */
+                               hsync-active = <1>; /* active high */
+                               vsync-active = <1>; /* active high */
+                               data-active = <1>; /* active high */
+                               pclk-sample = <1>; /* sample on rising edge */
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_i2c2>;
+       status = "okay";
+
+       rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&lcdif {
+       assigned-clocks = <&clks IMX6UL_CLK_LCDIF_PRE_SEL>;
+       assigned-clock-parents = <&clks IMX6UL_CLK_PLL5_VIDEO_DIV>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_lcd_data>, <&mux_lcd_ctrl>;
+       status = "okay";
+
+       port {
+               display_out: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_pwm>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_uart>;
+       status = "okay";
+};
+
+&usbotg1 {
+       /* USB-C connector */
+       disable-over-current;
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usbotg2 {
+       /* thermal sensor */
+       disable-over-current;
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usbphy1 {
+       fsl,tx-d-cal = <106>;
+};
+
+&usbphy2 {
+       fsl,tx-d-cal = <106>;
+};
+
+&usdhc1 {
+       /* MicroSD */
+       cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+       keep-power-in-suspend;
+       no-1-8-v;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&mux_sdhc1>, <&mux_sdhc1_cd>;
+       pinctrl-1 = <&mux_sdhc1_100mhz>, <&mux_sdhc1_cd>;
+       pinctrl-2 = <&mux_sdhc1_200mhz>, <&mux_sdhc1_cd>;
+       wakeup-source;
+       vmmc-supply = <&reg_vsd>;
+       status = "okay";
+};
+
+&usdhc2 {
+       /* eMMC */
+       keep-power-in-suspend;
+       no-1-8-v;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_sdhc2>;
+       wakeup-source;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mux_wdog>;
+};
+
+&iomuxc {
+       mux_adc: adcgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__GPIO1_IO07                0xb0
+               >;
+       };
+
+       mux_backlight_enable: blenablegrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO09__GPIO1_IO09                0x3008
+               >;
+       };
+
+       mux_charger_stat1: charger1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO01__GPIO1_IO01                0x3008
+               >;
+       };
+
+       mux_charger_stat2: charger2grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02                0x3008
+               >;
+       };
+
+       mux_csi: csi1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK                0x1b088
+                       MX6UL_PAD_CSI_VSYNC__CSI_VSYNC                  0x1b088
+                       MX6UL_PAD_CSI_HSYNC__CSI_HSYNC                  0x1b088
+                       MX6UL_PAD_CSI_DATA00__CSI_DATA02                0x1b088
+                       MX6UL_PAD_CSI_DATA01__CSI_DATA03                0x1b088
+                       MX6UL_PAD_CSI_DATA02__CSI_DATA04                0x1b088
+                       MX6UL_PAD_CSI_DATA03__CSI_DATA05                0x1b088
+                       MX6UL_PAD_CSI_DATA04__CSI_DATA06                0x1b088
+                       MX6UL_PAD_CSI_DATA05__CSI_DATA07                0x1b088
+                       MX6UL_PAD_CSI_DATA06__CSI_DATA08                0x1b088
+                       MX6UL_PAD_CSI_DATA07__CSI_DATA09                0x1b088
+               >;
+       };
+
+       mux_gc0308: gc0308grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_MCLK__CSI_MCLK                    0x1e038
+                       MX6UL_PAD_GPIO1_IO05__GPIO1_IO05                0x1b088
+                       MX6UL_PAD_GPIO1_IO06__GPIO1_IO06                0x1b088
+               >;
+       };
+
+       mux_gpio_keys: gpiokeygrp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11            0x3008
+                       MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12            0x3008
+                       MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13               0x3008
+                       MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10               0x3008
+                       MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09            0x3008
+                       MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15               0x3008
+                       MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08            0x3008
+                       MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14              0x3008
+                       MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03            0x3008
+                       MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01            0x3008
+               >;
+       };
+
+       mux_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL               0x4001b8b0
+                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA               0x4001b8b0
+               >;
+       };
+
+       mux_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_TX_DATA__I2C2_SCL               0x4001f8a8
+                       MX6UL_PAD_UART5_RX_DATA__I2C2_SDA               0x4001f8a8
+               >;
+       };
+
+       mux_ir_reset: irresetgrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03                0x3008
+               >;
+       };
+
+       mux_lcd_ctrl: lcdifctrlgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK                    0x79
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE              0x79
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC                0x79
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC                0x79
+               >;
+       };
+
+       mux_lcd_data: lcdifdatgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00              0x79
+                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01              0x79
+                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02              0x79
+                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03              0x79
+                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04              0x79
+                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05              0x79
+                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06              0x79
+                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07              0x79
+                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08              0x79
+                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09              0x79
+                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10              0x79
+                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11              0x79
+                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12              0x79
+                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13              0x79
+                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14              0x79
+                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15              0x79
+                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16              0x79
+                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17              0x79
+               >;
+       };
+
+       mux_led_ctrl: ledctrlgrp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02               0x3008
+               >;
+       };
+
+       mux_poweroff: poweroffgrp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04            0x3008
+               >;
+       };
+
+       mux_poweroff2: poweroff2grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06              0x3008
+               >;
+       };
+
+       mux_pwm: pwm1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO08__PWM1_OUT                  0x110b0
+               >;
+       };
+
+       mux_sdhc1: sdhc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD                   0x17059
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK                   0x10071
+                       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
+               >;
+       };
+
+       mux_sdhc1_100mhz: sdhc1-100mhz-grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD                   0x170b9
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK                   0x170b9
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0               0x170b9
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1               0x170b9
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2               0x170b9
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3               0x170b9
+               >;
+       };
+
+       mux_sdhc1_200mhz: sdhc1-200mhz-grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD                   0x170f9
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK                   0x170f9
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0               0x170f9
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1               0x170f9
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2               0x170f9
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3               0x170f9
+               >;
+       };
+
+       mux_sdhc1_cd: sdhc1-cd-grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19               0x17059
+               >;
+       };
+
+       mux_sdhc2: sdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK                 0x10069
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD                 0x17059
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0             0x17059
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1             0x17059
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2             0x17059
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3             0x17059
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4             0x17059
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5             0x17059
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6             0x17059
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7             0x17059
+               >;
+       };
+
+       mux_spi3: ecspi3grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI              0x100b1
+                       MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK            0x100b1
+                       MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20             0x3008
+               >;
+       };
+
+       mux_uart: uartgrp {
+               fsl,pins = <
+                       MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX           0x1b0b1
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX           0x1b0b1
+               >;
+       };
+
+       mux_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY             0x30b0
+               >;
+       };
+};
index 9c81c6baa2d39ae7cd73a34144598d513423c343..22dd72499ef27851f13fe02ece118f30cfbb40d4 100644 (file)
                                        clock-names = "snvs-rtc";
                                };
 
+                               snvs_poweroff: snvs-poweroff {
+                                       compatible = "syscon-poweroff";
+                                       regmap = <&snvs>;
+                                       offset = <0x38>;
+                                       value = <0x60>;
+                                       mask = <0x60>;
+                                       status = "disabled";
+                               };
+
                                snvs_pwrkey: snvs-powerkey {
                                        compatible = "fsl,sec-v4.0-pwrkey";
                                        regmap = <&snvs>;
index 6478a39b3be5e42cf81dd5c6233bd3fc719b5f27..e2e922bdc9e97e695bd74ea321c45dcb227f1434 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_QCOM) += \
+       msm8226-motorola-falcon.dtb \
        qcom-apq8016-sbc.dtb \
        qcom-apq8026-asus-sparrow.dtb \
        qcom-apq8026-huawei-sturgeon.dtb \
@@ -45,7 +46,9 @@ dtb-$(CONFIG_ARCH_QCOM) += \
        qcom-msm8974pro-fairphone-fp2.dtb \
        qcom-msm8974pro-oneplus-bacon.dtb \
        qcom-msm8974pro-samsung-klte.dtb \
+       qcom-msm8974pro-samsung-kltechn.dtb \
        qcom-msm8974pro-sony-xperia-shinano-castor.dtb \
+       qcom-msm8974pro-sony-xperia-shinano-leo.dtb \
        qcom-mdm9615-wp8548-mangoh-green.dtb \
        qcom-sdx55-mtp.dtb \
        qcom-sdx55-t55.dtb \
diff --git a/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts b/arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dts
new file mode 100644 (file)
index 0000000..029e1b1
--- /dev/null
@@ -0,0 +1,359 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+
+#include "qcom-msm8226.dtsi"
+#include "pm8226.dtsi"
+
+/delete-node/ &smem_region;
+
+/ {
+       model = "Motorola Moto G (2013)";
+       compatible = "motorola,falcon", "qcom,msm8226";
+       chassis-type = "handset";
+
+       aliases {
+               mmc0 = &sdhc_1;
+       };
+
+       chosen {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               framebuffer@3200000 {
+                       compatible = "simple-framebuffer";
+                       reg = <0x03200000 0x800000>;
+                       width = <720>;
+                       height = <1280>;
+                       stride = <(720 * 3)>;
+                       format = "r8g8b8";
+                       vsp-supply = <&reg_lcd_pos>;
+                       vsn-supply = <&reg_lcd_neg>;
+                       vddio-supply = <&vddio_disp_vreg>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               event-hall-sensor {
+                       label = "Hall Effect Sensor";
+                       gpios = <&tlmm 51 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <EV_SW>;
+                       linux,code = <SW_LID>;
+                       linux,can-disable;
+               };
+
+               key-volume-up {
+                       label = "Volume Up";
+                       gpios = <&tlmm 106 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       debounce-interval = <15>;
+               };
+       };
+
+       vddio_disp_vreg: regulator-vddio-disp {
+               compatible = "regulator-fixed";
+               regulator-name = "vddio_disp";
+               gpio = <&tlmm 34 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&pm8226_l8>;
+               startup-delay-us = <300>;
+               enable-active-high;
+               regulator-boot-on;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               framebuffer@3200000 {
+                       reg = <0x03200000 0x800000>;
+                       no-map;
+               };
+
+               dhob@f500000 {
+                       reg = <0x0f500000 0x40000>;
+                       no-map;
+               };
+
+               shob@f540000 {
+                       reg = <0x0f540000 0x2000>;
+                       no-map;
+               };
+
+               smem_region: smem@fa00000 {
+                       reg = <0x0fa00000 0x100000>;
+                       no-map;
+               };
+
+               /* Actually <0x0fa00000 0x500000>, but first 100000 is smem */
+               reserved@fb00000 {
+                       reg = <0x0fb00000 0x400000>;
+                       no-map;
+               };
+       };
+};
+
+&blsp1_i2c3 {
+       status = "okay";
+
+       regulator@3e {
+               compatible = "ti,tps65132";
+               reg = <0x3e>;
+               pinctrl-0 = <&reg_lcd_default>;
+               pinctrl-names = "default";
+
+               reg_lcd_pos: outp {
+                       regulator-name = "outp";
+                       regulator-min-microvolt = <4000000>;
+                       regulator-max-microvolt = <6000000>;
+                       regulator-active-discharge = <1>;
+                       regulator-boot-on;
+                       enable-gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
+               };
+
+               reg_lcd_neg: outn {
+                       regulator-name = "outn";
+                       regulator-min-microvolt = <4000000>;
+                       regulator-max-microvolt = <6000000>;
+                       regulator-active-discharge = <1>;
+                       regulator-boot-on;
+                       enable-gpios = <&tlmm 33 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       temperature-sensor@48 {
+               compatible = "ti,tmp108";
+               reg = <0x48>;
+               interrupts-extended = <&tlmm 13 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-0 = <&temp_alert_default>;
+               pinctrl-names = "default";
+               #thermal-sensor-cells = <0>;
+       };
+};
+
+&pm8226_resin {
+       linux,code = <KEY_VOLUMEDOWN>;
+       status = "okay";
+};
+
+&pm8226_vib {
+       status = "okay";
+};
+
+&rpm_requests {
+       regulators {
+               compatible = "qcom,rpm-pm8226-regulators";
+
+               pm8226_s3: s3 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1300000>;
+               };
+
+               pm8226_s4: s4 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2200000>;
+               };
+
+               pm8226_s5: s5 {
+                       regulator-min-microvolt = <1150000>;
+                       regulator-max-microvolt = <1150000>;
+               };
+
+               pm8226_l1: l1 {
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pm8226_l2: l2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pm8226_l3: l3 {
+                       regulator-min-microvolt = <750000>;
+                       regulator-max-microvolt = <1337500>;
+               };
+
+               pm8226_l4: l4 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pm8226_l5: l5 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pm8226_l6: l6 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-allow-set-load;
+               };
+
+               pm8226_l7: l7 {
+                       regulator-min-microvolt = <1850000>;
+                       regulator-max-microvolt = <1850000>;
+               };
+
+               pm8226_l8: l8 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8226_l9: l9 {
+                       regulator-min-microvolt = <2050000>;
+                       regulator-max-microvolt = <2050000>;
+               };
+
+               pm8226_l10: l10 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8226_l12: l12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8226_l14: l14 {
+                       regulator-min-microvolt = <2750000>;
+                       regulator-max-microvolt = <2750000>;
+               };
+
+               pm8226_l15: l15 {
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+
+               pm8226_l16: l16 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3350000>;
+               };
+
+               pm8226_l17: l17 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pm8226_l18: l18 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pm8226_l19: l19 {
+                       regulator-min-microvolt = <2850000>;
+                       regulator-max-microvolt = <2850000>;
+               };
+
+               pm8226_l20: l20 {
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3075000>;
+               };
+
+               pm8226_l21: l21 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-allow-set-load;
+               };
+
+               pm8226_l22: l22 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pm8226_l23: l23 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pm8226_l24: l24 {
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1350000>;
+               };
+
+               pm8226_l25: l25 {
+                       regulator-min-microvolt = <1775000>;
+                       regulator-max-microvolt = <2125000>;
+               };
+
+               pm8226_l26: l26 {
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pm8226_l27: l27 {
+                       regulator-min-microvolt = <2050000>;
+                       regulator-max-microvolt = <2050000>;
+               };
+
+               pm8226_l28: l28 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3400000>;
+                       regulator-boot-on;
+               };
+
+               pm8226_lvs1: lvs1 {
+                       regulator-always-on;
+               };
+       };
+};
+
+&sdhc_1 {
+       vmmc-supply = <&pm8226_l17>;
+       vqmmc-supply = <&pm8226_l6>;
+
+       bus-width = <8>;
+       non-removable;
+
+       status = "okay";
+};
+
+&smbb {
+       qcom,fast-charge-safe-current = <2000000>;
+       qcom,fast-charge-current-limit = <1900000>;
+       qcom,fast-charge-safe-voltage = <4400000>;
+       qcom,minimum-input-voltage = <4300000>;
+
+       status = "okay";
+};
+
+&tlmm {
+       reg_lcd_default: reg-lcd-default-state {
+               pins = "gpio31", "gpio33";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+               output-high;
+       };
+
+       reg_vddio_disp_default: reg-vddio-disp-default-state {
+               pins = "gpio34";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+               output-high;
+       };
+
+       temp_alert_default: temp-alert-default-state {
+               pins = "gpio13";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+               output-disable;
+       };
+};
+
+&usb {
+       extcon = <&smbb>;
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usb_hs_phy {
+       extcon = <&smbb>;
+       v1p8-supply = <&pm8226_l10>;
+       v3p3-supply = <&pm8226_l20>;
+};
index 9a5ba978775aaa7c784cc676f799cf400333a26f..11e60b74c3c9d84c30e9eba5fbdb639a2595a646 100644 (file)
@@ -87,7 +87,7 @@
                };
 
                idle-states {
-                       CPU_SPC: spc {
+                       CPU_SPC: cpu-spc {
                                compatible = "qcom,idle-state-spc",
                                                "arm,idle-state";
                                entry-latency-us = <400>;
                                 <&gcc PCIE_PHY_RESET>;
                        reset-names = "axi", "ahb", "por", "pci", "phy";
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                hdmi: hdmi-tx@4a00000 {
index 8204e64d9a97fec9d45cce3edb4dfd2052c9bf28..ca53dff820ef4ba1edfda75a29961ea9d7beb262 100644 (file)
@@ -79,7 +79,7 @@
                };
 
                idle-states {
-                       CPU_SPC: spc {
+                       CPU_SPC: cpu-spc {
                                compatible = "qcom,idle-state-spc",
                                                "arm,idle-state";
                                entry-latency-us = <150>;
index 681cb3fc8085dfd6ab9fe89daa0de281c157f641..0fb65f2bbcdfe79acfb745a1050824005a488df3 100644 (file)
                                      "phy_ahb";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                qpic_bam: dma-controller@7984000 {
                        reg = <0x90000 0x64>;
                        status = "disabled";
 
-                       ethphy0: ethernet-phy@0 {
+                       ethernet-phy-package@0 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "qcom,qca8075-package";
                                reg = <0>;
-                       };
 
-                       ethphy1: ethernet-phy@1 {
-                               reg = <1>;
-                       };
+                               qcom,tx-drive-strength-milliwatt = <300>;
 
-                       ethphy2: ethernet-phy@2 {
-                               reg = <2>;
-                       };
+                               ethphy0: ethernet-phy@0 {
+                                       reg = <0>;
+                               };
 
-                       ethphy3: ethernet-phy@3 {
-                               reg = <3>;
-                       };
+                               ethphy1: ethernet-phy@1 {
+                                       reg = <1>;
+                               };
+
+                               ethphy2: ethernet-phy@2 {
+                                       reg = <2>;
+                               };
+
+                               ethphy3: ethernet-phy@3 {
+                                       reg = <3>;
+                               };
 
-                       ethphy4: ethernet-phy@4 {
-                               reg = <4>;
+                               ethphy4: ethernet-phy@4 {
+                                       reg = <4>;
+                               };
                        };
                };
 
index 2eb6758b6a3a6f7c80bddfb89b31644fa51eaf5b..f128510d844556c989201d412308e5aed86e1f8c 100644 (file)
 
                        status = "disabled";
                        perst-gpios = <&qcom_pinmux 3 GPIO_ACTIVE_LOW>;
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1: pcie@1b700000 {
 
                        status = "disabled";
                        perst-gpios = <&qcom_pinmux 48 GPIO_ACTIVE_LOW>;
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie2: pcie@1b900000 {
 
                        status = "disabled";
                        perst-gpios = <&qcom_pinmux 63 GPIO_ACTIVE_LOW>;
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                qsgmii_csr: syscon@1bb00000 {
index 36328dbe4212bd6038527386ee9c82af5f656d01..1ba403b83cb1d4e92b218ab6b9a44ed4f9d4308a 100644 (file)
@@ -26,7 +26,7 @@
 };
 
 &CPU_SLEEP_0 {
-       compatible = "qcom,idle-state-spc";
+       compatible = "qcom,idle-state-spc", "arm,idle-state";
 };
 
 &cpu0_acc {
index 5efc38d712cce272c9b5517b2202721d70119905..5651bb31bd54247db23019a7fdd77fe10e7fcf0e 100644 (file)
@@ -14,6 +14,8 @@
        #size-cells = <1>;
        interrupt-parent = <&intc>;
 
+       chosen { };
+
        clocks {
                xo_board: xo_board {
                        compatible = "fixed-clock";
@@ -85,7 +87,7 @@
                };
 
                idle-states {
-                       CPU_SPC: spc {
+                       CPU_SPC: cpu-spc {
                                compatible = "qcom,idle-state-spc",
                                                "arm,idle-state";
                                entry-latency-us = <150>;
                };
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x0>;
        };
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte-common.dtsi
new file mode 100644 (file)
index 0000000..b5443fd
--- /dev/null
@@ -0,0 +1,818 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro.dtsi"
+#include "pma8084.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       chassis-type = "handset";
+
+       aliases {
+               serial0 = &blsp1_uart1;
+               mmc0 = &sdhc_1; /* SDC1 eMMC slot */
+               mmc1 = &sdhc_3; /* SDC2 SD card slot */
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_pin_a>;
+
+               key-volume-down {
+                       label = "volume_down";
+                       gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       debounce-interval = <15>;
+               };
+
+               key-home {
+                       label = "home_key";
+                       gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_HOMEPAGE>;
+                       wakeup-source;
+                       debounce-interval = <15>;
+               };
+
+               key-volume-up {
+                       label = "volume_up";
+                       gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
+                       linux,input-type = <1>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       debounce-interval = <15>;
+               };
+       };
+
+       i2c-gpio-touchkey {
+               compatible = "i2c-gpio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               sda-gpios = <&tlmm 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&tlmm 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c_touchkey_pins>;
+
+               touchkey@20 {
+                       compatible = "cypress,tm2-touchkey";
+                       reg = <0x20>;
+
+                       interrupt-parent = <&pma8084_gpios>;
+                       interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&touchkey_pin>;
+
+                       vcc-supply = <&max77826_ldo15>;
+                       vdd-supply = <&pma8084_l19>;
+
+                       linux,keycodes = <KEY_APPSELECT KEY_BACK>;
+               };
+       };
+
+       i2c_led_gpio: i2c-gpio-led {
+               compatible = "i2c-gpio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c_led_gpioex_pins>;
+
+               i2c-gpio,delay-us = <2>;
+
+               gpio_expander: gpio@20 {
+                       compatible = "nxp,pcal6416";
+                       reg = <0x20>;
+
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       vcc-supply = <&pma8084_s4>;
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gpioex_pin>;
+
+                       reset-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>;
+               };
+
+               led-controller@30 {
+                       compatible = "panasonic,an30259a";
+                       reg = <0x30>;
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       led@1 {
+                               reg = <1>;
+                               function = LED_FUNCTION_STATUS;
+                               color = <LED_COLOR_ID_RED>;
+                       };
+
+                       led@2 {
+                               reg = <2>;
+                               function = LED_FUNCTION_STATUS;
+                               color = <LED_COLOR_ID_GREEN>;
+                       };
+
+                       led@3 {
+                               reg = <3>;
+                               function = LED_FUNCTION_STATUS;
+                               color = <LED_COLOR_ID_BLUE>;
+                       };
+               };
+       };
+
+       vreg_wlan: wlan-regulator {
+               compatible = "regulator-fixed";
+
+               regulator-name = "wl-reg";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vreg_panel: panel-regulator {
+               compatible = "regulator-fixed";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&panel_en_pin>;
+
+               regulator-name = "panel-vddr-reg";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+
+               gpio = <&pma8084_gpios 14 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vreg_vph_pwr: vreg-vph-pwr {
+               compatible = "regulator-fixed";
+               regulator-name = "vph-pwr";
+
+               regulator-min-microvolt = <3600000>;
+               regulator-max-microvolt = <3600000>;
+
+               regulator-always-on;
+       };
+};
+
+&blsp1_i2c2 {
+       status = "okay";
+
+       touchscreen@20 {
+               compatible = "syna,rmi4-i2c";
+               reg = <0x20>;
+
+               interrupt-parent = <&pma8084_gpios>;
+               interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
+
+               vdd-supply = <&max77826_ldo13>;
+               vio-supply = <&pma8084_lvs2>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&touch_pin>;
+
+               syna,startup-delay-ms = <100>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               rmi4-f01@1 {
+                       reg = <0x1>;
+                       syna,nosleep-mode = <1>;
+               };
+
+               rmi4-f12@12 {
+                       reg = <0x12>;
+                       syna,sensor-type = <1>;
+               };
+       };
+};
+
+&blsp1_i2c6 {
+       status = "okay";
+
+       pmic@60 {
+               reg = <0x60>;
+               compatible = "maxim,max77826";
+
+               regulators {
+                       max77826_ldo1: LDO1 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       max77826_ldo2: LDO2 {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <1000000>;
+                       };
+
+                       max77826_ldo3: LDO3 {
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       max77826_ldo4: LDO4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       max77826_ldo5: LDO5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       max77826_ldo6: LDO6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       max77826_ldo7: LDO7 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       max77826_ldo8: LDO8 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       max77826_ldo9: LDO9 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       max77826_ldo10: LDO10 {
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2950000>;
+                       };
+
+                       max77826_ldo11: LDO11 {
+                               regulator-min-microvolt = <2700000>;
+                               regulator-max-microvolt = <2950000>;
+                       };
+
+                       max77826_ldo12: LDO12 {
+                               regulator-min-microvolt = <2500000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       max77826_ldo13: LDO13 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       max77826_ldo14: LDO14 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       max77826_ldo15: LDO15 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       max77826_buck: BUCK {
+                               regulator-min-microvolt = <1225000>;
+                               regulator-max-microvolt = <1225000>;
+                       };
+
+                       max77826_buckboost: BUCKBOOST {
+                               regulator-min-microvolt = <3400000>;
+                               regulator-max-microvolt = <3400000>;
+                       };
+               };
+       };
+};
+
+&blsp1_uart2 {
+       status = "okay";
+};
+
+&blsp2_i2c6 {
+       status = "okay";
+
+       fuelgauge@36 {
+               compatible = "maxim,max17048";
+               reg = <0x36>;
+
+               maxim,double-soc;
+               maxim,rcomp = /bits/ 8 <0x56>;
+
+               interrupt-parent = <&pma8084_gpios>;
+               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&fuelgauge_pin>;
+       };
+};
+
+&blsp2_uart2 {
+       status = "okay";
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&blsp2_uart2_pins_active>;
+       pinctrl-1 = <&blsp2_uart2_pins_sleep>;
+
+       bluetooth {
+               compatible = "brcm,bcm43540-bt";
+               max-speed = <3000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_pins>;
+               device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
+               shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
+               interrupt-parent = <&tlmm>;
+               interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "host-wakeup";
+       };
+};
+
+&gpu {
+       status = "okay";
+};
+
+&mdss {
+       status = "okay";
+};
+
+&mdss_dsi0 {
+       status = "okay";
+
+       vdda-supply = <&pma8084_l2>;
+       vdd-supply = <&pma8084_l22>;
+       vddio-supply = <&pma8084_l12>;
+
+       panel: panel@0 {
+               reg = <0>;
+               compatible = "samsung,s6e3fa2";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
+
+               iovdd-supply = <&pma8084_lvs4>;
+               vddr-supply = <&vreg_panel>;
+
+               reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&mdss_dsi0_out>;
+                       };
+               };
+       };
+};
+
+&mdss_dsi0_out {
+       remote-endpoint = <&panel_in>;
+       data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+       status = "okay";
+
+       vddio-supply = <&pma8084_l12>;
+};
+
+&pma8084_gpios {
+       gpio_keys_pin_a: gpio-keys-active-state {
+               pins = "gpio2", "gpio3", "gpio5";
+               function = "normal";
+
+               bias-pull-up;
+               power-source = <PMA8084_GPIO_S4>;
+       };
+
+       touchkey_pin: touchkey-int-state {
+               pins = "gpio6";
+               function = "normal";
+               bias-disable;
+               input-enable;
+               power-source = <PMA8084_GPIO_S4>;
+       };
+
+       touch_pin: touchscreen-int-state {
+               pins = "gpio8";
+               function = "normal";
+               bias-disable;
+               input-enable;
+               power-source = <PMA8084_GPIO_S4>;
+       };
+
+       panel_en_pin: panel-en-state {
+               pins = "gpio14";
+               function = "normal";
+               bias-pull-up;
+               power-source = <PMA8084_GPIO_S4>;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+       };
+
+       wlan_sleep_clk_pin: wlan-sleep-clk-state {
+               pins = "gpio16";
+               function = "func2";
+
+               output-high;
+               power-source = <PMA8084_GPIO_S4>;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+       };
+
+       panel_rst_pin: panel-rst-state {
+               pins = "gpio17";
+               function = "normal";
+               bias-disable;
+               power-source = <PMA8084_GPIO_S4>;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+       };
+
+       fuelgauge_pin: fuelgauge-int-state {
+               pins = "gpio21";
+               function = "normal";
+               bias-disable;
+               input-enable;
+               power-source = <PMA8084_GPIO_S4>;
+       };
+};
+
+&remoteproc_adsp {
+       status = "okay";
+       cx-supply = <&pma8084_s2>;
+};
+
+&remoteproc_mss {
+       status = "okay";
+       cx-supply = <&pma8084_s2>;
+       mss-supply = <&pma8084_s6>;
+       mx-supply = <&pma8084_s1>;
+       pll-supply = <&pma8084_l12>;
+};
+
+&rpm_requests {
+       regulators-0 {
+               compatible = "qcom,rpm-pma8084-regulators";
+
+               pma8084_s1: s1 {
+                       regulator-min-microvolt = <675000>;
+                       regulator-max-microvolt = <1050000>;
+                       regulator-always-on;
+               };
+
+               pma8084_s2: s2 {
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+
+               pma8084_s3: s3 {
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1300000>;
+               };
+
+               pma8084_s4: s4 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_s5: s5 {
+                       regulator-min-microvolt = <2150000>;
+                       regulator-max-microvolt = <2150000>;
+               };
+
+               pma8084_s6: s6 {
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+
+               pma8084_l1: l1 {
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pma8084_l2: l2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pma8084_l3: l3 {
+                       regulator-min-microvolt = <1050000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pma8084_l4: l4 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pma8084_l5: l5 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_l6: l6 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_l7: l7 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_l8: l8 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_l9: l9 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pma8084_l10: l10 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pma8084_l11: l11 {
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1300000>;
+               };
+
+               pma8084_l12: l12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               pma8084_l13: l13 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pma8084_l14: l14 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pma8084_l15: l15 {
+                       regulator-min-microvolt = <2050000>;
+                       regulator-max-microvolt = <2050000>;
+               };
+
+               pma8084_l16: l16 {
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2700000>;
+               };
+
+               pma8084_l17: l17 {
+                       regulator-min-microvolt = <2850000>;
+                       regulator-max-microvolt = <2850000>;
+               };
+
+               pma8084_l18: l18 {
+                       regulator-min-microvolt = <2850000>;
+                       regulator-max-microvolt = <2850000>;
+               };
+
+               pma8084_l19: l19 {
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+
+               pma8084_l20: l20 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-system-load = <200000>;
+                       regulator-allow-set-load;
+               };
+
+               pma8084_l21: l21 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-system-load = <200000>;
+                       regulator-allow-set-load;
+               };
+
+               pma8084_l22: l22 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+
+               pma8084_l23: l23 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+               };
+
+               pma8084_l24: l24 {
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3075000>;
+               };
+
+               pma8084_l25: l25 {
+                       regulator-min-microvolt = <2100000>;
+                       regulator-max-microvolt = <2100000>;
+               };
+
+               pma8084_l26: l26 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2050000>;
+               };
+
+               pma8084_l27: l27 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pma8084_lvs1: lvs1 {};
+               pma8084_lvs2: lvs2 {};
+               pma8084_lvs3: lvs3 {};
+               pma8084_lvs4: lvs4 {};
+
+               pma8084_5vs1: 5vs1 {};
+       };
+};
+
+&sdhc_1 {
+       status = "okay";
+
+       vmmc-supply = <&pma8084_l20>;
+       vqmmc-supply = <&pma8084_s4>;
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sdc1_on>;
+       pinctrl-1 = <&sdc1_off>;
+};
+
+&sdhc_2 {
+       status = "okay";
+       max-frequency = <100000000>;
+       vmmc-supply = <&vreg_wlan>;
+       vqmmc-supply = <&pma8084_s4>;
+       non-removable;
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sdc2_on>;
+       pinctrl-1 = <&sdc2_off>;
+
+       wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+
+               /*
+                * Allow all klte* variants to load the same NVRAM file,
+                * as they have little difference in the WiFi part.
+                */
+               brcm,board-type = "samsung,klte";
+
+               interrupt-parent = <&tlmm>;
+               interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "host-wake";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
+       };
+};
+
+&sdhc_3 {
+       status = "okay";
+       max-frequency = <100000000>;
+       vmmc-supply = <&pma8084_l21>;
+       vqmmc-supply = <&pma8084_l13>;
+
+       /*
+        * cd-gpio is intentionally disabled. If enabled, an SD card
+        * present during boot is not initialized correctly. Without
+        * cd-gpios the driver resorts to polling, so hotplug works.
+        */
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdc3_on /* &sdhc3_cd_pin */>;
+       /* cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; */
+};
+
+&tlmm {
+       /* This seems suspicious, but somebody with this device should look into it. */
+       blsp2_uart2_pins_active: blsp2-uart2-pins-active-state {
+               pins = "gpio45", "gpio46", "gpio47", "gpio48";
+               function = "blsp_uart8";
+               drive-strength = <8>;
+               bias-disable;
+       };
+
+       blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep-state {
+               pins = "gpio45", "gpio46", "gpio47", "gpio48";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-pull-down;
+       };
+
+       bt_pins: bt-pins-state {
+               hostwake-pins {
+                       pins = "gpio75";
+                       function = "gpio";
+                       drive-strength = <16>;
+               };
+
+               devwake-pins {
+                       pins = "gpio91";
+                       function = "gpio";
+                       drive-strength = <2>;
+               };
+       };
+
+       sdc1_on: sdhc1-on-state {
+               clk-pins {
+                       pins = "sdc1_clk";
+                       drive-strength = <4>;
+                       bias-disable;
+               };
+
+               cmd-data-pins {
+                       pins = "sdc1_cmd", "sdc1_data";
+                       drive-strength = <4>;
+                       bias-pull-up;
+               };
+       };
+
+       sdc3_on: sdc3-on-state {
+               pins = "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+               function = "sdc3";
+               drive-strength = <8>;
+               bias-disable;
+       };
+
+       sdhc3_cd_pin: sdc3-cd-on-state {
+               pins = "gpio62";
+               function = "gpio";
+
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       sdc2_on: sdhc2-on-state {
+               clk-pins {
+                       pins = "sdc2_clk";
+                       drive-strength = <6>;
+                       bias-disable;
+               };
+
+               cmd-data-pins {
+                       pins = "sdc2_cmd", "sdc2_data";
+                       drive-strength = <6>;
+                       bias-pull-up;
+               };
+       };
+
+       i2c_touchkey_pins: i2c-touchkey-state {
+               pins = "gpio95", "gpio96";
+               function = "gpio";
+               bias-pull-up;
+       };
+
+       i2c_led_gpioex_pins: i2c-led-gpioex-state {
+               function = "gpio";
+               bias-pull-down;
+       };
+
+       gpioex_pin: gpioex-state {
+               pins = "gpio145";
+               function = "gpio";
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+
+       wifi_pin: wifi-state {
+               pins = "gpio92";
+               function = "gpio";
+               bias-pull-down;
+       };
+
+       panel_te_pin: panel-state {
+               pins = "gpio12";
+               function = "mdp_vsync";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
+&usb {
+       status = "okay";
+
+       phys = <&usb_hs1_phy>;
+       phy-select = <&tcsr 0xb000 0>;
+
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+};
+
+&usb_hs1_phy {
+       status = "okay";
+
+       v1p8-supply = <&pma8084_l6>;
+       v3p3-supply = <&pma8084_l24>;
+
+       qcom,init-seq = /bits/ 8 <0x1 0x64>;
+};
index b93539e2b87e91b2ec03c346f71078a2bd6b9044..954665f3a9dd94f02b5614ad2e370aaf7cef5311 100644 (file)
 // SPDX-License-Identifier: GPL-2.0
-#include "qcom-msm8974pro.dtsi"
-#include "pma8084.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
-#include <dt-bindings/leds/common.h>
+#include "qcom-msm8974pro-samsung-klte-common.dtsi"
 
 / {
        model = "Samsung Galaxy S5";
        compatible = "samsung,klte", "qcom,msm8974pro", "qcom,msm8974";
-       chassis-type = "handset";
-
-       aliases {
-               serial0 = &blsp1_uart1;
-               mmc0 = &sdhc_1; /* SDC1 eMMC slot */
-               mmc1 = &sdhc_3; /* SDC2 SD card slot */
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&gpio_keys_pin_a>;
-
-               key-volume-down {
-                       label = "volume_down";
-                       gpios = <&pma8084_gpios 2 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_VOLUMEDOWN>;
-                       debounce-interval = <15>;
-               };
-
-               key-home {
-                       label = "home_key";
-                       gpios = <&pma8084_gpios 3 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_HOMEPAGE>;
-                       wakeup-source;
-                       debounce-interval = <15>;
-               };
-
-               key-volume-up {
-                       label = "volume_up";
-                       gpios = <&pma8084_gpios 5 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_VOLUMEUP>;
-                       debounce-interval = <15>;
-               };
-       };
-
-       i2c-gpio-touchkey {
-               compatible = "i2c-gpio";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               sda-gpios = <&tlmm 95 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-               scl-gpios = <&tlmm 96 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&i2c_touchkey_pins>;
-
-               touchkey@20 {
-                       compatible = "cypress,tm2-touchkey";
-                       reg = <0x20>;
-
-                       interrupt-parent = <&pma8084_gpios>;
-                       interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&touchkey_pin>;
-
-                       vcc-supply = <&max77826_ldo15>;
-                       vdd-supply = <&pma8084_l19>;
-
-                       linux,keycodes = <KEY_APPSELECT KEY_BACK>;
-               };
-       };
-
-       i2c-gpio-led {
-               compatible = "i2c-gpio";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               scl-gpios = <&tlmm 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-               sda-gpios = <&tlmm 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&i2c_led_gpioex_pins>;
-
-               i2c-gpio,delay-us = <2>;
-
-               gpio_expander: gpio@20 {
-                       compatible = "nxp,pcal6416";
-                       reg = <0x20>;
-
-                       gpio-controller;
-                       #gpio-cells = <2>;
-
-                       vcc-supply = <&pma8084_s4>;
-
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&gpioex_pin>;
-
-                       reset-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>;
-               };
-
-               led-controller@30 {
-                       compatible = "panasonic,an30259a";
-                       reg = <0x30>;
-
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       led@1 {
-                               reg = <1>;
-                               function = LED_FUNCTION_STATUS;
-                               color = <LED_COLOR_ID_RED>;
-                       };
-
-                       led@2 {
-                               reg = <2>;
-                               function = LED_FUNCTION_STATUS;
-                               color = <LED_COLOR_ID_GREEN>;
-                       };
-
-                       led@3 {
-                               reg = <3>;
-                               function = LED_FUNCTION_STATUS;
-                               color = <LED_COLOR_ID_BLUE>;
-                       };
-               };
-       };
-
-       vreg_wlan: wlan-regulator {
-               compatible = "regulator-fixed";
-
-               regulator-name = "wl-reg";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-
-               gpio = <&gpio_expander 8 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       vreg_panel: panel-regulator {
-               compatible = "regulator-fixed";
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&panel_en_pin>;
-
-               regulator-name = "panel-vddr-reg";
-               regulator-min-microvolt = <1500000>;
-               regulator-max-microvolt = <1500000>;
-
-               gpio = <&pma8084_gpios 14 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-       };
-
-       vreg_vph_pwr: vreg-vph-pwr {
-               compatible = "regulator-fixed";
-               regulator-name = "vph-pwr";
-
-               regulator-min-microvolt = <3600000>;
-               regulator-max-microvolt = <3600000>;
-
-               regulator-always-on;
-       };
-};
-
-&blsp1_i2c2 {
-       status = "okay";
-
-       touchscreen@20 {
-               compatible = "syna,rmi4-i2c";
-               reg = <0x20>;
-
-               interrupt-parent = <&pma8084_gpios>;
-               interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
-
-               vdd-supply = <&max77826_ldo13>;
-               vio-supply = <&pma8084_lvs2>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&touch_pin>;
-
-               syna,startup-delay-ms = <100>;
-
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               rmi4-f01@1 {
-                       reg = <0x1>;
-                       syna,nosleep-mode = <1>;
-               };
-
-               rmi4-f12@12 {
-                       reg = <0x12>;
-                       syna,sensor-type = <1>;
-               };
-       };
-};
-
-&blsp1_i2c6 {
-       status = "okay";
-
-       pmic@60 {
-               reg = <0x60>;
-               compatible = "maxim,max77826";
-
-               regulators {
-                       max77826_ldo1: LDO1 {
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1200000>;
-                       };
-
-                       max77826_ldo2: LDO2 {
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
-                       };
-
-                       max77826_ldo3: LDO3 {
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1200000>;
-                       };
-
-                       max77826_ldo4: LDO4 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
-
-                       max77826_ldo5: LDO5 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
-
-                       max77826_ldo6: LDO6 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       max77826_ldo7: LDO7 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
-
-                       max77826_ldo8: LDO8 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       max77826_ldo9: LDO9 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
-
-                       max77826_ldo10: LDO10 {
-                               regulator-min-microvolt = <2800000>;
-                               regulator-max-microvolt = <2950000>;
-                       };
-
-                       max77826_ldo11: LDO11 {
-                               regulator-min-microvolt = <2700000>;
-                               regulator-max-microvolt = <2950000>;
-                       };
-
-                       max77826_ldo12: LDO12 {
-                               regulator-min-microvolt = <2500000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       max77826_ldo13: LDO13 {
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       max77826_ldo14: LDO14 {
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                       };
-
-                       max77826_ldo15: LDO15 {
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
-
-                       max77826_buck: BUCK {
-                               regulator-min-microvolt = <1225000>;
-                               regulator-max-microvolt = <1225000>;
-                       };
-
-                       max77826_buckboost: BUCKBOOST {
-                               regulator-min-microvolt = <3400000>;
-                               regulator-max-microvolt = <3400000>;
-                       };
-               };
-       };
-};
-
-&blsp1_uart2 {
-       status = "okay";
-};
-
-&blsp2_i2c6 {
-       status = "okay";
-
-       fuelgauge@36 {
-               compatible = "maxim,max17048";
-               reg = <0x36>;
-
-               maxim,double-soc;
-               maxim,rcomp = /bits/ 8 <0x56>;
-
-               interrupt-parent = <&pma8084_gpios>;
-               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&fuelgauge_pin>;
-       };
-};
-
-&blsp2_uart2 {
-       status = "okay";
-
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&blsp2_uart2_pins_active>;
-       pinctrl-1 = <&blsp2_uart2_pins_sleep>;
-
-       bluetooth {
-               compatible = "brcm,bcm43540-bt";
-               max-speed = <3000000>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bt_pins>;
-               device-wakeup-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
-               shutdown-gpios = <&gpio_expander 9 GPIO_ACTIVE_HIGH>;
-               interrupt-parent = <&tlmm>;
-               interrupts = <75 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "host-wakeup";
-       };
-};
-
-&gpu {
-       status = "okay";
-};
-
-&mdss {
-       status = "okay";
-};
-
-&mdss_dsi0 {
-       status = "okay";
-
-       vdda-supply = <&pma8084_l2>;
-       vdd-supply = <&pma8084_l22>;
-       vddio-supply = <&pma8084_l12>;
-
-       panel: panel@0 {
-               reg = <0>;
-               compatible = "samsung,s6e3fa2";
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&panel_te_pin &panel_rst_pin>;
-
-               iovdd-supply = <&pma8084_lvs4>;
-               vddr-supply = <&vreg_panel>;
-
-               reset-gpios = <&pma8084_gpios 17 GPIO_ACTIVE_LOW>;
-
-               port {
-                       panel_in: endpoint {
-                               remote-endpoint = <&mdss_dsi0_out>;
-                       };
-               };
-       };
-};
-
-&mdss_dsi0_out {
-       remote-endpoint = <&panel_in>;
-       data-lanes = <0 1 2 3>;
-};
-
-&mdss_dsi0_phy {
-       status = "okay";
-
-       vddio-supply = <&pma8084_l12>;
 };
 
-&pma8084_gpios {
-       gpio_keys_pin_a: gpio-keys-active-state {
-               pins = "gpio2", "gpio3", "gpio5";
-               function = "normal";
-
-               bias-pull-up;
-               power-source = <PMA8084_GPIO_S4>;
-       };
-
-       touchkey_pin: touchkey-int-state {
-               pins = "gpio6";
-               function = "normal";
-               bias-disable;
-               input-enable;
-               power-source = <PMA8084_GPIO_S4>;
-       };
-
-       touch_pin: touchscreen-int-state {
-               pins = "gpio8";
-               function = "normal";
-               bias-disable;
-               input-enable;
-               power-source = <PMA8084_GPIO_S4>;
-       };
-
-       panel_en_pin: panel-en-state {
-               pins = "gpio14";
-               function = "normal";
-               bias-pull-up;
-               power-source = <PMA8084_GPIO_S4>;
-               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
-       };
-
-       wlan_sleep_clk_pin: wlan-sleep-clk-state {
-               pins = "gpio16";
-               function = "func2";
-
-               output-high;
-               power-source = <PMA8084_GPIO_S4>;
-               qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
-       };
-
-       panel_rst_pin: panel-rst-state {
-               pins = "gpio17";
-               function = "normal";
-               bias-disable;
-               power-source = <PMA8084_GPIO_S4>;
-               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
-       };
-
-       fuelgauge_pin: fuelgauge-int-state {
-               pins = "gpio21";
-               function = "normal";
-               bias-disable;
-               input-enable;
-               power-source = <PMA8084_GPIO_S4>;
-       };
+&i2c_led_gpio {
+       scl-gpios = <&tlmm 121 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&tlmm 120 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 };
 
-&remoteproc_adsp {
-       status = "okay";
-       cx-supply = <&pma8084_s2>;
-};
-
-&remoteproc_mss {
-       status = "okay";
-       cx-supply = <&pma8084_s2>;
-       mss-supply = <&pma8084_s6>;
-       mx-supply = <&pma8084_s1>;
-       pll-supply = <&pma8084_l12>;
-};
-
-&rpm_requests {
-       regulators-0 {
-               compatible = "qcom,rpm-pma8084-regulators";
-
-               pma8084_s1: s1 {
-                       regulator-min-microvolt = <675000>;
-                       regulator-max-microvolt = <1050000>;
-                       regulator-always-on;
-               };
-
-               pma8084_s2: s2 {
-                       regulator-min-microvolt = <500000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-
-               pma8084_s3: s3 {
-                       regulator-min-microvolt = <1300000>;
-                       regulator-max-microvolt = <1300000>;
-               };
-
-               pma8084_s4: s4 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_s5: s5 {
-                       regulator-min-microvolt = <2150000>;
-                       regulator-max-microvolt = <2150000>;
-               };
-
-               pma8084_s6: s6 {
-                       regulator-min-microvolt = <1050000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-
-               pma8084_l1: l1 {
-                       regulator-min-microvolt = <1225000>;
-                       regulator-max-microvolt = <1225000>;
-               };
-
-               pma8084_l2: l2 {
-                       regulator-min-microvolt = <1200000>;
-                       regulator-max-microvolt = <1200000>;
-               };
-
-               pma8084_l3: l3 {
-                       regulator-min-microvolt = <1050000>;
-                       regulator-max-microvolt = <1200000>;
-               };
-
-               pma8084_l4: l4 {
-                       regulator-min-microvolt = <1200000>;
-                       regulator-max-microvolt = <1225000>;
-               };
-
-               pma8084_l5: l5 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_l6: l6 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_l7: l7 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_l8: l8 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_l9: l9 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2950000>;
-               };
-
-               pma8084_l10: l10 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2950000>;
-               };
-
-               pma8084_l11: l11 {
-                       regulator-min-microvolt = <1300000>;
-                       regulator-max-microvolt = <1300000>;
-               };
-
-               pma8084_l12: l12 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-always-on;
-               };
-
-               pma8084_l13: l13 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2950000>;
-               };
-
-               pma8084_l14: l14 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pma8084_l15: l15 {
-                       regulator-min-microvolt = <2050000>;
-                       regulator-max-microvolt = <2050000>;
-               };
-
-               pma8084_l16: l16 {
-                       regulator-min-microvolt = <2700000>;
-                       regulator-max-microvolt = <2700000>;
-               };
-
-               pma8084_l17: l17 {
-                       regulator-min-microvolt = <2850000>;
-                       regulator-max-microvolt = <2850000>;
-               };
-
-               pma8084_l18: l18 {
-                       regulator-min-microvolt = <2850000>;
-                       regulator-max-microvolt = <2850000>;
-               };
-
-               pma8084_l19: l19 {
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-               };
-
-               pma8084_l20: l20 {
-                       regulator-min-microvolt = <2950000>;
-                       regulator-max-microvolt = <2950000>;
-                       regulator-system-load = <200000>;
-                       regulator-allow-set-load;
-               };
-
-               pma8084_l21: l21 {
-                       regulator-min-microvolt = <2950000>;
-                       regulator-max-microvolt = <2950000>;
-                       regulator-system-load = <200000>;
-                       regulator-allow-set-load;
-               };
-
-               pma8084_l22: l22 {
-                       regulator-min-microvolt = <3000000>;
-                       regulator-max-microvolt = <3300000>;
-               };
-
-               pma8084_l23: l23 {
-                       regulator-min-microvolt = <3000000>;
-                       regulator-max-microvolt = <3000000>;
-               };
-
-               pma8084_l24: l24 {
-                       regulator-min-microvolt = <3075000>;
-                       regulator-max-microvolt = <3075000>;
-               };
-
-               pma8084_l25: l25 {
-                       regulator-min-microvolt = <2100000>;
-                       regulator-max-microvolt = <2100000>;
-               };
-
-               pma8084_l26: l26 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2050000>;
-               };
-
-               pma8084_l27: l27 {
-                       regulator-min-microvolt = <1000000>;
-                       regulator-max-microvolt = <1225000>;
-               };
-
-               pma8084_lvs1: lvs1 {};
-               pma8084_lvs2: lvs2 {};
-               pma8084_lvs3: lvs3 {};
-               pma8084_lvs4: lvs4 {};
-
-               pma8084_5vs1: 5vs1 {};
-       };
-};
-
-&sdhc_1 {
-       status = "okay";
-
-       vmmc-supply = <&pma8084_l20>;
-       vqmmc-supply = <&pma8084_s4>;
-
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sdc1_on>;
-       pinctrl-1 = <&sdc1_off>;
-};
-
-&sdhc_2 {
-       status = "okay";
-       max-frequency = <100000000>;
-       vmmc-supply = <&vreg_wlan>;
-       vqmmc-supply = <&pma8084_s4>;
-       non-removable;
-
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sdc2_on>;
-       pinctrl-1 = <&sdc2_off>;
-
-       wifi@1 {
-               reg = <1>;
-               compatible = "brcm,bcm4329-fmac";
-
-               interrupt-parent = <&tlmm>;
-               interrupts = <92 IRQ_TYPE_LEVEL_HIGH>;
-               interrupt-names = "host-wake";
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&wlan_sleep_clk_pin &wifi_pin>;
-       };
-};
-
-&sdhc_3 {
-       status = "okay";
-       max-frequency = <100000000>;
-       vmmc-supply = <&pma8084_l21>;
-       vqmmc-supply = <&pma8084_l13>;
-
-       /*
-        * cd-gpio is intentionally disabled. If enabled, an SD card
-        * present during boot is not initialized correctly. Without
-        * cd-gpios the driver resorts to polling, so hotplug works.
-        */
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdc3_on /* &sdhc3_cd_pin */>;
-       /* cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>; */
-};
-
-&tlmm {
-       /* This seems suspicious, but somebody with this device should look into it. */
-       blsp2_uart2_pins_active: blsp2-uart2-pins-active-state {
-               pins = "gpio45", "gpio46", "gpio47", "gpio48";
-               function = "blsp_uart8";
-               drive-strength = <8>;
-               bias-disable;
-       };
-
-       blsp2_uart2_pins_sleep: blsp2-uart2-pins-sleep-state {
-               pins = "gpio45", "gpio46", "gpio47", "gpio48";
-               function = "gpio";
-               drive-strength = <2>;
-               bias-pull-down;
-       };
-
-       bt_pins: bt-pins-state {
-               hostwake-pins {
-                       pins = "gpio75";
-                       function = "gpio";
-                       drive-strength = <16>;
-               };
-
-               devwake-pins {
-                       pins = "gpio91";
-                       function = "gpio";
-                       drive-strength = <2>;
-               };
-       };
-
-       sdc1_on: sdhc1-on-state {
-               clk-pins {
-                       pins = "sdc1_clk";
-                       drive-strength = <4>;
-                       bias-disable;
-               };
-
-               cmd-data-pins {
-                       pins = "sdc1_cmd", "sdc1_data";
-                       drive-strength = <4>;
-                       bias-pull-up;
-               };
-       };
-
-       sdc3_on: sdc3-on-state {
-               pins = "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
-               function = "sdc3";
-               drive-strength = <8>;
-               bias-disable;
-       };
-
-       sdhc3_cd_pin: sdc3-cd-on-state {
-               pins = "gpio62";
-               function = "gpio";
-
-               drive-strength = <2>;
-               bias-disable;
-       };
-
-       sdc2_on: sdhc2-on-state {
-               clk-pins {
-                       pins = "sdc2_clk";
-                       drive-strength = <6>;
-                       bias-disable;
-               };
-
-               cmd-data-pins {
-                       pins = "sdc2_cmd", "sdc2_data";
-                       drive-strength = <6>;
-                       bias-pull-up;
-               };
-       };
-
-       i2c_touchkey_pins: i2c-touchkey-state {
-               pins = "gpio95", "gpio96";
-               function = "gpio";
-               bias-pull-up;
-       };
-
-       i2c_led_gpioex_pins: i2c-led-gpioex-state {
-               pins = "gpio120", "gpio121";
-               function = "gpio";
-               bias-pull-down;
-       };
-
-       gpioex_pin: gpioex-state {
-               pins = "gpio145";
-               function = "gpio";
-               bias-pull-up;
-               drive-strength = <2>;
-       };
-
-       wifi_pin: wifi-state {
-               pins = "gpio92";
-               function = "gpio";
-               bias-pull-down;
-       };
-
-       panel_te_pin: panel-state {
-               pins = "gpio12";
-               function = "mdp_vsync";
-               drive-strength = <2>;
-               bias-disable;
-       };
-};
-
-&usb {
-       status = "okay";
-
-       phys = <&usb_hs1_phy>;
-       phy-select = <&tcsr 0xb000 0>;
-
-       hnp-disable;
-       srp-disable;
-       adp-disable;
-};
-
-&usb_hs1_phy {
-       status = "okay";
-
-       v1p8-supply = <&pma8084_l6>;
-       v3p3-supply = <&pma8084_l24>;
-
-       qcom,init-seq = /bits/ 8 <0x1 0x64>;
+&i2c_led_gpioex_pins {
+       pins = "gpio120", "gpio121";
 };
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-kltechn.dts
new file mode 100644 (file)
index 0000000..b902e31
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-samsung-klte-common.dtsi"
+
+/ {
+       model = "Samsung Galaxy S5 China";
+       compatible = "samsung,kltechn", "samsung,klte", "qcom,msm8974pro", "qcom,msm8974";
+};
+
+&i2c_led_gpio {
+       scl-gpios = <&tlmm 61 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&tlmm 60 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+&i2c_led_gpioex_pins {
+       pins = "gpio60", "gpio61";
+};
index ee94741a26ed6d591d8343666c6546e411670488..409d1798de34ecbdb5edad84dfc8d12737fb9521 100644 (file)
@@ -1,60 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
-#include "qcom-msm8974pro.dtsi"
-#include "pm8841.dtsi"
-#include "pm8941.dtsi"
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/leds/common.h>
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
 
 / {
        model = "Sony Xperia Z2 Tablet";
        compatible = "sony,xperia-castor", "qcom,msm8974pro", "qcom,msm8974";
        chassis-type = "tablet";
 
-       aliases {
-               serial0 = &blsp1_uart2;
-               serial1 = &blsp2_uart1;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&gpio_keys_pin_a>;
-
-               key-volume-down {
-                       label = "volume_down";
-                       gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_VOLUMEDOWN>;
-               };
-
-               key-camera-snapshot {
-                       label = "camera_snapshot";
-                       gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_CAMERA>;
-               };
-
-               key-camera-focus {
-                       label = "camera_focus";
-                       gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_CAMERA_FOCUS>;
-               };
-
-               key-volume-up {
-                       label = "volume_up";
-                       gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <1>;
-                       linux,code = <KEY_VOLUMEUP>;
-               };
-       };
-
        vreg_bl_vddio: lcd-backlight-vddio {
                compatible = "regulator-fixed";
                regulator-name = "vreg_bl_vddio";
                vin-supply = <&pm8941_s3>;
                startup-delay-us = <70000>;
 
-               pinctrl-names = "default";
                pinctrl-0 = <&lcd_backlight_en_pin_a>;
-       };
-
-       vreg_vsp: lcd-dcdc-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "vreg_vsp";
-               regulator-min-microvolt = <5600000>;
-               regulator-max-microvolt = <5600000>;
-
-               gpio = <&pm8941_gpios 20 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&lcd_dcdc_en_pin_a>;
-       };
-
-       vreg_boost: vreg-boost {
-               compatible = "regulator-fixed";
-
-               regulator-name = "vreg-boost";
-               regulator-min-microvolt = <3150000>;
-               regulator-max-microvolt = <3150000>;
-
-               regulator-always-on;
-               regulator-boot-on;
-
-               gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-
                pinctrl-names = "default";
-               pinctrl-0 = <&boost_bypass_n_pin>;
        };
-
-       vreg_vph_pwr: vreg-vph-pwr {
-               compatible = "regulator-fixed";
-               regulator-name = "vph-pwr";
-
-               regulator-min-microvolt = <3600000>;
-               regulator-max-microvolt = <3600000>;
-
-               regulator-always-on;
-       };
-
-       vreg_wlan: wlan-regulator {
-               compatible = "regulator-fixed";
-
-               regulator-name = "wl-reg";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-
-               gpio = <&pm8941_gpios 18 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&wlan_regulator_pin>;
-       };
-};
-
-&blsp1_uart2 {
-       status = "okay";
 };
 
-&blsp2_i2c2 {
-       status = "okay";
+&blsp2_i2c5 {
        clock-frequency = <355000>;
 
-       synaptics@2c {
-               compatible = "syna,rmi4-i2c";
-               reg = <0x2c>;
-
-               interrupt-parent = <&tlmm>;
-               interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
-
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               vdd-supply = <&pm8941_l22>;
-               vio-supply = <&pm8941_lvs3>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&ts_int_pin>;
-
-               syna,startup-delay-ms = <100>;
-
-               rmi4-f01@1 {
-                       reg = <0x1>;
-                       syna,nosleep-mode = <1>;
-               };
-
-               rmi4-f11@11 {
-                       reg = <0x11>;
-                       syna,sensor-type = <1>;
-                       touchscreen-inverted-x;
-               };
-       };
-};
-
-&blsp2_i2c5 {
        status = "okay";
-       clock-frequency = <355000>;
 
        lp8566_wled: backlight@2c {
                compatible = "ti,lp8556";
                        rom-addr = /bits/ 8 <0xa0>;
                        rom-val = /bits/ 8 <0xff>;
                };
+
                rom-a1h {
                        rom-addr = /bits/ 8 <0xa1>;
                        rom-val = /bits/ 8 <0x3f>;
                };
+
                rom-a2h {
                        rom-addr = /bits/ 8 <0xa2>;
                        rom-val = /bits/ 8 <0x20>;
                };
+
                rom-a3h {
                        rom-addr = /bits/ 8 <0xa3>;
                        rom-val = /bits/ 8 <0x5e>;
                };
+
                rom-a4h {
                        rom-addr = /bits/ 8 <0xa4>;
                        rom-val = /bits/ 8 <0x02>;
                };
+
                rom-a5h {
                        rom-addr = /bits/ 8 <0xa5>;
                        rom-val = /bits/ 8 <0x04>;
                };
+
                rom-a6h {
                        rom-addr = /bits/ 8 <0xa6>;
                        rom-val = /bits/ 8 <0x80>;
                };
+
                rom-a7h {
                        rom-addr = /bits/ 8 <0xa7>;
                        rom-val = /bits/ 8 <0xf7>;
                };
+
                rom-a9h {
                        rom-addr = /bits/ 8 <0xa9>;
                        rom-val = /bits/ 8 <0x80>;
                };
+
                rom-aah {
                        rom-addr = /bits/ 8 <0xaa>;
                        rom-val = /bits/ 8 <0x0f>;
                };
+
                rom-aeh {
                        rom-addr = /bits/ 8 <0xae>;
                        rom-val = /bits/ 8 <0x0f>;
                compatible = "brcm,bcm43438-bt";
                max-speed = <3000000>;
 
-               pinctrl-names = "default";
                pinctrl-0 = <&bt_host_wake_pin>, <&bt_dev_wake_pin>, <&bt_reg_on_pin>;
+               pinctrl-names = "default";
 
                host-wakeup-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
                device-wakeup-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
        };
 };
 
-&pm8941_coincell {
-       status = "okay";
-
-       qcom,rset-ohms = <2100>;
-       qcom,vset-millivolts = <3000>;
-};
-
 &pm8941_gpios {
-       gpio_keys_pin_a: gpio-keys-active-state {
-               pins = "gpio2", "gpio5";
-               function = "normal";
-
-               bias-pull-up;
-               power-source = <PM8941_GPIO_S3>;
-       };
-
        bt_reg_on_pin: bt-reg-on-state {
                pins = "gpio16";
                function = "normal";
-
                output-low;
                power-source = <PM8941_GPIO_S3>;
        };
-
-       wlan_sleep_clk_pin: wl-sleep-clk-state {
-               pins = "gpio17";
-               function = "func2";
-
-               output-high;
-               power-source = <PM8941_GPIO_S3>;
-       };
-
-       wlan_regulator_pin: wl-reg-active-state {
-               pins = "gpio18";
-               function = "normal";
-
-               bias-disable;
-               power-source = <PM8941_GPIO_S3>;
-       };
-
-       lcd_dcdc_en_pin_a: lcd-dcdc-en-active-state {
-               pins = "gpio20";
-               function = "normal";
-
-               bias-disable;
-               power-source = <PM8941_GPIO_S3>;
-               input-disable;
-               output-low;
-       };
-
-};
-
-&pm8941_lpg {
-       status = "okay";
-
-       qcom,power-source = <1>;
-
-       multi-led {
-               color = <LED_COLOR_ID_RGB>;
-               function = LED_FUNCTION_STATUS;
-
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               led@5 {
-                       reg = <5>;
-                       color = <LED_COLOR_ID_BLUE>;
-               };
-
-               led@6 {
-                       reg = <6>;
-                       color = <LED_COLOR_ID_GREEN>;
-               };
-
-               led@7 {
-                       reg = <7>;
-                       color = <LED_COLOR_ID_RED>;
-               };
-       };
-};
-
-&remoteproc_adsp {
-       cx-supply = <&pm8841_s2>;
-       status = "okay";
-};
-
-&remoteproc_mss {
-       cx-supply = <&pm8841_s2>;
-       mss-supply = <&pm8841_s3>;
-       mx-supply = <&pm8841_s1>;
-       pll-supply = <&pm8941_l12>;
-       status = "okay";
 };
 
 &rpm_requests {
-       regulators-0 {
-               compatible = "qcom,rpm-pm8841-regulators";
-
-               pm8841_s1: s1 {
-                       regulator-min-microvolt = <675000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-
-               pm8841_s2: s2 {
-                       regulator-min-microvolt = <500000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-
-               pm8841_s3: s3 {
-                       regulator-min-microvolt = <500000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-
-               pm8841_s4: s4 {
-                       regulator-min-microvolt = <500000>;
-                       regulator-max-microvolt = <1050000>;
-               };
-       };
-
        regulators-1 {
-               compatible = "qcom,rpm-pm8941-regulators";
-
-               vdd_l1_l3-supply = <&pm8941_s1>;
-               vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
-               vdd_l4_l11-supply = <&pm8941_s1>;
-               vdd_l5_l7-supply = <&pm8941_s2>;
-               vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
-               vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
-               vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
-               vdd_l21-supply = <&vreg_boost>;
-
-               pm8941_s1: s1 {
-                       regulator-min-microvolt = <1300000>;
-                       regulator-max-microvolt = <1300000>;
-                       regulator-always-on;
-                       regulator-boot-on;
-               };
-
-               pm8941_s2: s2 {
-                       regulator-min-microvolt = <2150000>;
-                       regulator-max-microvolt = <2150000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_s3: s3 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-system-load = <154000>;
-                       regulator-always-on;
-                       regulator-boot-on;
-               };
-
-               pm8941_s4: s4 {
-                       regulator-min-microvolt = <5000000>;
-                       regulator-max-microvolt = <5000000>;
-               };
-
-               pm8941_l1: l1 {
-                       regulator-min-microvolt = <1225000>;
-                       regulator-max-microvolt = <1225000>;
-                       regulator-always-on;
-                       regulator-boot-on;
-               };
-
-               pm8941_l2: l2 {
-                       regulator-min-microvolt = <1200000>;
-                       regulator-max-microvolt = <1200000>;
-               };
-
-               pm8941_l3: l3 {
-                       regulator-min-microvolt = <1200000>;
-                       regulator-max-microvolt = <1200000>;
-               };
-
-               pm8941_l4: l4 {
-                       regulator-min-microvolt = <1225000>;
-                       regulator-max-microvolt = <1225000>;
-               };
-
-               pm8941_l5: l5 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pm8941_l6: l6 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_l7: l7 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_l8: l8 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pm8941_l9: l9 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2950000>;
-               };
-
                pm8941_l11: l11 {
                        regulator-min-microvolt = <1300000>;
                        regulator-max-microvolt = <1350000>;
                };
 
-               pm8941_l12: l12 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-always-on;
-                       regulator-boot-on;
-               };
-
-               pm8941_l13: l13 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <2950000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_l14: l14 {
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-               };
-
-               pm8941_l15: l15 {
-                       regulator-min-microvolt = <2050000>;
-                       regulator-max-microvolt = <2050000>;
-               };
-
-               pm8941_l16: l16 {
-                       regulator-min-microvolt = <2700000>;
-                       regulator-max-microvolt = <2700000>;
-               };
-
-               pm8941_l17: l17 {
-                       regulator-min-microvolt = <2700000>;
-                       regulator-max-microvolt = <2700000>;
-               };
-
-               pm8941_l18: l18 {
-                       regulator-min-microvolt = <2850000>;
-                       regulator-max-microvolt = <2850000>;
-               };
-
                pm8941_l19: l19 {
                        regulator-min-microvolt = <2850000>;
                        regulator-max-microvolt = <2850000>;
                };
-
-               pm8941_l20: l20 {
-                       regulator-min-microvolt = <2950000>;
-                       regulator-max-microvolt = <2950000>;
-                       regulator-system-load = <500000>;
-                       regulator-allow-set-load;
-                       regulator-boot-on;
-               };
-
-               pm8941_l21: l21 {
-                       regulator-min-microvolt = <2950000>;
-                       regulator-max-microvolt = <2950000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_l22: l22 {
-                       regulator-min-microvolt = <3000000>;
-                       regulator-max-microvolt = <3000000>;
-               };
-
-               pm8941_l23: l23 {
-                       regulator-min-microvolt = <2800000>;
-                       regulator-max-microvolt = <2800000>;
-               };
-
-               pm8941_l24: l24 {
-                       regulator-min-microvolt = <3075000>;
-                       regulator-max-microvolt = <3075000>;
-                       regulator-boot-on;
-               };
-
-               pm8941_lvs3: lvs3 {};
-       };
-};
-
-&sdhc_1 {
-       status = "okay";
-
-       vmmc-supply = <&pm8941_l20>;
-       vqmmc-supply = <&pm8941_s3>;
-
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sdc1_on>;
-       pinctrl-1 = <&sdc1_off>;
-};
-
-&sdhc_2 {
-       status = "okay";
-
-       vmmc-supply = <&pm8941_l21>;
-       vqmmc-supply = <&pm8941_l13>;
-
-       cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
-
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sdc2_on>;
-       pinctrl-1 = <&sdc2_off>;
-};
-
-&sdhc_3 {
-       status = "okay";
-
-       max-frequency = <100000000>;
-       vmmc-supply = <&vreg_wlan>;
-       non-removable;
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdc3_on>;
-
-       #address-cells = <1>;
-       #size-cells = <0>;
-
-       bcrmf@1 {
-               compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
-               reg = <1>;
-
-               brcm,drive-strength = <10>;
-
-               pinctrl-names = "default";
-               pinctrl-0 = <&wlan_sleep_clk_pin>;
        };
 };
 
        status = "okay";
 };
 
-&tlmm {
-       lcd_backlight_en_pin_a: lcd-backlight-vddio-state {
-               pins = "gpio69";
-               function = "gpio";
-               drive-strength = <10>;
-               output-low;
-               bias-disable;
-       };
-
-       sdc1_on: sdc1-on-state {
-               clk-pins {
-                       pins = "sdc1_clk";
-                       drive-strength = <16>;
-                       bias-disable;
-               };
-
-               cmd-data-pins {
-                       pins = "sdc1_cmd", "sdc1_data";
-                       drive-strength = <10>;
-                       bias-pull-up;
-               };
-       };
-
-       sdc2_on: sdc2-on-state {
-               clk-pins {
-                       pins = "sdc2_clk";
-                       drive-strength = <6>;
-                       bias-disable;
-               };
-
-               cmd-data-pins {
-                       pins = "sdc2_cmd", "sdc2_data";
-                       drive-strength = <6>;
-                       bias-pull-up;
-               };
-
-               cd-pins {
-                       pins = "gpio62";
-                       function = "gpio";
-                       drive-strength = <2>;
-                       bias-disable;
-               };
-       };
-
-       sdc3_on: sdc3-on-state {
-               clk-pins {
-                       pins = "gpio40";
-                       function = "sdc3";
-                       drive-strength = <10>;
-                       bias-disable;
-               };
-
-               cmd-pins {
-                       pins = "gpio39";
-                       function = "sdc3";
-                       drive-strength = <10>;
-                       bias-pull-up;
-               };
-
-               data-pins {
-                       pins = "gpio35", "gpio36", "gpio37", "gpio38";
-                       function = "sdc3";
-                       drive-strength = <10>;
-                       bias-pull-up;
-               };
-       };
+&synaptics_touchscreen {
+       vio-supply = <&pm8941_lvs3>;
+};
 
-       ts_int_pin: ts-int-pin-state {
-               pins = "gpio86";
+&tlmm {
+       bt_dev_wake_pin: bt-dev-wake-state {
+               pins = "gpio96";
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
                output-low;
        };
 
-       bt_dev_wake_pin: bt-dev-wake-state {
-               pins = "gpio96";
+       lcd_backlight_en_pin_a: lcd-backlight-vddio-state {
+               pins = "gpio69";
                function = "gpio";
-               drive-strength = <2>;
+               drive-strength = <10>;
+               output-low;
                bias-disable;
        };
 };
-
-&usb {
-       status = "okay";
-
-       phys = <&usb_hs1_phy>;
-       phy-select = <&tcsr 0xb000 0>;
-       extcon = <&smbb>, <&usb_id>;
-       vbus-supply = <&chg_otg>;
-
-       hnp-disable;
-       srp-disable;
-       adp-disable;
-};
-
-&usb_hs1_phy {
-       status = "okay";
-
-       v1p8-supply = <&pm8941_l6>;
-       v3p3-supply = <&pm8941_l24>;
-
-       extcon = <&smbb>;
-       qcom,init-seq = /bits/ 8 <0x1 0x64>;
-};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-common.dtsi
new file mode 100644 (file)
index 0000000..e129bb1
--- /dev/null
@@ -0,0 +1,539 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro.dtsi"
+#include "pm8841.dtsi"
+#include "pm8941.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+       aliases {
+               mmc0 = &sdhc_1;
+               mmc1 = &sdhc_2;
+               serial0 = &blsp1_uart2;
+               serial1 = &blsp2_uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-0 = <&gpio_keys_pin_a>;
+               pinctrl-names = "default";
+
+               key-volume-down {
+                       label = "volume_down";
+                       gpios = <&pm8941_gpios 2 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       debounce-interval = <15>;
+               };
+
+               key-volume-up {
+                       label = "volume_up";
+                       gpios = <&pm8941_gpios 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       debounce-interval = <15>;
+               };
+       };
+
+       vreg_vsp: lcd-dcdc-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vreg_vsp";
+               regulator-min-microvolt = <5600000>;
+               regulator-max-microvolt = <5600000>;
+
+               gpio = <&pm8941_gpios 20 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-0 = <&lcd_dcdc_en_pin_a>;
+               pinctrl-names = "default";
+       };
+
+       vreg_boost: vreg-boost {
+               compatible = "regulator-fixed";
+
+               regulator-name = "vreg-boost";
+               regulator-min-microvolt = <3150000>;
+               regulator-max-microvolt = <3150000>;
+
+               regulator-always-on;
+               regulator-boot-on;
+
+               gpio = <&pm8941_gpios 21 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&boost_bypass_n_pin>;
+       };
+
+       vreg_vph_pwr: vreg-vph-pwr {
+               compatible = "regulator-fixed";
+               regulator-name = "vph-pwr";
+
+               regulator-min-microvolt = <3600000>;
+               regulator-max-microvolt = <3600000>;
+
+               regulator-always-on;
+       };
+
+       vreg_wlan: wlan-regulator {
+               compatible = "regulator-fixed";
+
+               regulator-name = "wl-reg";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpio = <&pm8941_gpios 18 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-0 = <&wlan_regulator_pin>;
+               pinctrl-names = "default";
+       };
+};
+
+&blsp1_uart2 {
+       status = "okay";
+};
+
+&blsp2_i2c2 {
+       clock-frequency = <355000>;
+
+       status = "okay";
+
+       synaptics_touchscreen: synaptics@2c {
+               compatible = "syna,rmi4-i2c";
+               reg = <0x2c>;
+
+               interrupt-parent = <&tlmm>;
+               interrupts = <86 IRQ_TYPE_EDGE_FALLING>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd-supply = <&pm8941_l22>;
+               /* vio-supply is set in dts */
+
+               pinctrl-0 = <&ts_int_pin>;
+               pinctrl-names = "default";
+
+               syna,startup-delay-ms = <100>;
+
+               rmi4-f01@1 {
+                       reg = <0x1>;
+                       syna,nosleep-mode = <1>;
+               };
+
+               rmi4-f11@11 {
+                       reg = <0x11>;
+                       syna,sensor-type = <1>;
+                       touchscreen-inverted-x;
+               };
+       };
+};
+
+&pm8941_coincell {
+       qcom,rset-ohms = <2100>;
+       qcom,vset-millivolts = <3000>;
+
+       status = "okay";
+};
+
+&pm8941_gpios {
+       gpio_keys_pin_a: gpio-keys-active-state {
+               pins = "gpio2", "gpio5";
+               function = "normal";
+               bias-pull-up;
+               power-source = <PM8941_GPIO_S3>;
+       };
+
+       wlan_sleep_clk_pin: wl-sleep-clk-state {
+               pins = "gpio17";
+               function = "func2";
+               output-high;
+               power-source = <PM8941_GPIO_S3>;
+       };
+
+       wlan_regulator_pin: wl-reg-active-state {
+               pins = "gpio18";
+               function = "normal";
+               bias-disable;
+               power-source = <PM8941_GPIO_S3>;
+       };
+
+       lcd_dcdc_en_pin_a: lcd-dcdc-en-active-state {
+               pins = "gpio20";
+               function = "normal";
+               bias-disable;
+               power-source = <PM8941_GPIO_S3>;
+               input-disable;
+               output-low;
+       };
+};
+
+&pm8941_lpg {
+       qcom,power-source = <1>;
+
+       status = "okay";
+
+       multi-led {
+               color = <LED_COLOR_ID_RGB>;
+               function = LED_FUNCTION_STATUS;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               led@5 {
+                       reg = <5>;
+                       color = <LED_COLOR_ID_BLUE>;
+               };
+
+               led@6 {
+                       reg = <6>;
+                       color = <LED_COLOR_ID_GREEN>;
+               };
+
+               led@7 {
+                       reg = <7>;
+                       color = <LED_COLOR_ID_RED>;
+               };
+       };
+};
+
+&pm8941_vib {
+       status = "okay";
+};
+
+&remoteproc_adsp {
+       cx-supply = <&pm8841_s2>;
+       status = "okay";
+};
+
+&remoteproc_mss {
+       cx-supply = <&pm8841_s2>;
+       mss-supply = <&pm8841_s3>;
+       mx-supply = <&pm8841_s1>;
+       pll-supply = <&pm8941_l12>;
+       status = "okay";
+};
+
+&rpm_requests {
+       regulators-0 {
+               compatible = "qcom,rpm-pm8841-regulators";
+
+               pm8841_s1: s1 {
+                       regulator-min-microvolt = <675000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+
+               pm8841_s2: s2 {
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+
+               pm8841_s3: s3 {
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+
+               pm8841_s4: s4 {
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1050000>;
+               };
+       };
+
+       regulators-1 {
+               compatible = "qcom,rpm-pm8941-regulators";
+
+               vdd_l1_l3-supply = <&pm8941_s1>;
+               vdd_l2_lvs1_2_3-supply = <&pm8941_s3>;
+               vdd_l4_l11-supply = <&pm8941_s1>;
+               vdd_l5_l7-supply = <&pm8941_s2>;
+               vdd_l6_l12_l14_l15-supply = <&pm8941_s2>;
+               vdd_l9_l10_l17_l22-supply = <&vreg_boost>;
+               vdd_l13_l20_l23_l24-supply = <&vreg_boost>;
+               vdd_l21-supply = <&vreg_boost>;
+
+               pm8941_s1: s1 {
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1300000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               pm8941_s2: s2 {
+                       regulator-min-microvolt = <2150000>;
+                       regulator-max-microvolt = <2150000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_s3: s3 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-system-load = <154000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               pm8941_s4: s4 {
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+               };
+
+               pm8941_l1: l1 {
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               pm8941_l2: l2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pm8941_l3: l3 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+
+               pm8941_l4: l4 {
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+
+               pm8941_l5: l5 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8941_l6: l6 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_l7: l7 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_l8: l8 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8941_l9: l9 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+
+               pm8941_l12: l12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+
+               pm8941_l13: l13 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_l14: l14 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               pm8941_l15: l15 {
+                       regulator-min-microvolt = <2050000>;
+                       regulator-max-microvolt = <2050000>;
+               };
+
+               pm8941_l16: l16 {
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2700000>;
+               };
+
+               pm8941_l17: l17 {
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2700000>;
+               };
+
+               pm8941_l18: l18 {
+                       regulator-min-microvolt = <2850000>;
+                       regulator-max-microvolt = <2850000>;
+               };
+
+               pm8941_l20: l20 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-system-load = <500000>;
+                       regulator-allow-set-load;
+                       regulator-boot-on;
+               };
+
+               pm8941_l21: l21 {
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_l22: l22 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+               };
+
+               pm8941_l23: l23 {
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+
+               pm8941_l24: l24 {
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3075000>;
+                       regulator-boot-on;
+               };
+
+               pm8941_lvs3: lvs3 {};
+       };
+};
+
+&sdhc_1 {
+       vmmc-supply = <&pm8941_l20>;
+       vqmmc-supply = <&pm8941_s3>;
+
+       pinctrl-0 = <&sdc1_on>;
+       pinctrl-1 = <&sdc1_off>;
+       pinctrl-names = "default", "sleep";
+
+       status = "okay";
+};
+
+&sdhc_2 {
+       vmmc-supply = <&pm8941_l21>;
+       vqmmc-supply = <&pm8941_l13>;
+
+       cd-gpios = <&tlmm 62 GPIO_ACTIVE_LOW>;
+
+       pinctrl-0 = <&sdc2_on>;
+       pinctrl-1 = <&sdc2_off>;
+       pinctrl-names = "default", "sleep";
+
+       status = "okay";
+};
+
+&sdhc_3 {
+       max-frequency = <100000000>;
+       vmmc-supply = <&vreg_wlan>;
+       non-removable;
+
+       pinctrl-0 = <&sdc3_on>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       wifi@1 {
+               compatible = "brcm,bcm4339-fmac", "brcm,bcm4329-fmac";
+               reg = <1>;
+
+               brcm,drive-strength = <10>;
+
+               pinctrl-0 = <&wlan_sleep_clk_pin>;
+               pinctrl-names = "default";
+       };
+};
+
+&tlmm {
+       sdc1_on: sdc1-on-state {
+               clk-pins {
+                       pins = "sdc1_clk";
+                       drive-strength = <16>;
+                       bias-disable;
+               };
+
+               cmd-data-pins {
+                       pins = "sdc1_cmd", "sdc1_data";
+                       drive-strength = <10>;
+                       bias-pull-up;
+               };
+       };
+
+       sdc2_on: sdc2-on-state {
+               clk-pins {
+                       pins = "sdc2_clk";
+                       drive-strength = <6>;
+                       bias-disable;
+               };
+
+               cmd-data-pins {
+                       pins = "sdc2_cmd", "sdc2_data";
+                       drive-strength = <6>;
+                       bias-pull-up;
+               };
+
+               cd-pins {
+                       pins = "gpio62";
+                       function = "gpio";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+       };
+
+       sdc3_on: sdc3-on-state {
+               clk-pins {
+                       pins = "gpio40";
+                       function = "sdc3";
+                       drive-strength = <10>;
+                       bias-disable;
+               };
+
+               cmd-pins {
+                       pins = "gpio39";
+                       function = "sdc3";
+                       drive-strength = <10>;
+                       bias-pull-up;
+               };
+
+               data-pins {
+                       pins = "gpio35", "gpio36", "gpio37", "gpio38";
+                       function = "sdc3";
+                       drive-strength = <10>;
+                       bias-pull-up;
+               };
+       };
+
+       ts_int_pin: ts-int-pin-state {
+               pins = "gpio86";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
+&usb {
+       phys = <&usb_hs1_phy>;
+       phy-select = <&tcsr 0xb000 0>;
+       extcon = <&smbb>, <&usb_id>;
+       vbus-supply = <&chg_otg>;
+
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+
+       status = "okay";
+};
+
+&usb_hs1_phy {
+       v1p8-supply = <&pm8941_l6>;
+       v3p3-supply = <&pm8941_l24>;
+
+       extcon = <&smbb>;
+       qcom,init-seq = /bits/ 8 <0x1 0x64>;
+
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts b/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-leo.dts
new file mode 100644 (file)
index 0000000..1ed6e1c
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-msm8974pro-sony-xperia-shinano-common.dtsi"
+
+/ {
+       model = "Sony Xperia Z3";
+       compatible = "sony,xperia-leo", "qcom,msm8974pro", "qcom,msm8974";
+       chassis-type = "handset";
+
+       gpio-keys {
+               key-camera-snapshot {
+                       label = "camera_snapshot";
+                       gpios = <&pm8941_gpios 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_CAMERA>;
+                       debounce-interval = <15>;
+               };
+
+               key-camera-focus {
+                       label = "camera_focus";
+                       gpios = <&pm8941_gpios 4 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_CAMERA_FOCUS>;
+                       debounce-interval = <15>;
+               };
+       };
+};
+
+&gpio_keys_pin_a {
+       pins = "gpio2", "gpio3", "gpio4", "gpio5";
+};
+
+&smbb {
+       usb-charge-current-limit = <1500000>;
+       qcom,fast-charge-safe-current = <3000000>;
+       qcom,fast-charge-current-limit = <2150000>;
+       qcom,fast-charge-safe-voltage = <4400000>;
+       qcom,fast-charge-high-threshold-voltage = <4350000>;
+       qcom,auto-recharge-threshold-voltage = <4280000>;
+       qcom,minimum-input-voltage = <4200000>;
+
+       status = "okay";
+};
+
+&synaptics_touchscreen {
+       vio-supply = <&pm8941_s3>;
+};
index edc9aaf828c8395c5ebf299003d4fc9c80d1e592..68fa5859d26343f8253475d5403f9b8966dead34 100644 (file)
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie_ep: pcie-ep@1c00000 {
index e6d8da6faffb55763e84b6b97e683d49838fdc2d..08ea4c551ed005544d5e3970dc91be6b47deefa3 100644 (file)
                                     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 216 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
                                     <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "eri", "rxi", "txi", "bri";
                        clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
                        clock-names = "fck";
                        power-domains = <&cpg_clocks>;
index ac654ff45d0e9a9c78ff2c94870b2b2b188075f5..9a2ae282a46ba4b160d2218cc6c52dfba6dc9e2f 100644 (file)
                             <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
        };
 
+       tmu0: timer@e61e0000 {
+               compatible = "renesas,tmu-r8a73a4", "renesas,tmu";
+               reg = <0 0xe61e0000 0 0x30>;
+               interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tuni0", "tuni1", "tuni2";
+               clocks = <&mstp1_clks R8A73A4_CLK_TMU0>;
+               clock-names = "fck";
+               power-domains = <&pd_c5>;
+               status = "disabled";
+       };
+
+       tmu3: timer@fff80000 {
+               compatible = "renesas,tmu-r8a73a4", "renesas,tmu";
+               reg = <0 0xfff80000 0 0x30>;
+               interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tuni0", "tuni1", "tuni2";
+               clocks = <&mstp1_clks R8A73A4_CLK_TMU3>;
+               clock-names = "fck";
+               power-domains = <&pd_a3r>;
+               status = "disabled";
+       };
+
        dbsc1: memory-controller@e6790000 {
                compatible = "renesas,dbsc-r8a73a4";
                reg = <0 0xe6790000 0 0x10000>;
                };
 
                /* Gate clocks */
+               mstp1_clks: mstp1_clks@e6150134 {
+                       compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
+                       reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>;
+                       clocks = <&cp_clk>, <&mp_clk>;
+                       #clock-cells = <1>;
+                       clock-indices = <
+                               R8A73A4_CLK_TMU0 R8A73A4_CLK_TMU3
+                       >;
+                       clock-output-names =
+                               "tmu0", "tmu3";
+               };
                mstp2_clks: mstp2_clks@e6150138 {
                        compatible = "renesas,r8a73a4-mstp-clocks", "renesas,cpg-mstp-clocks";
                        reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>;
index 16d146db824a09e6e0a86ecf9096a5ed5d76639f..d55c344c1cd2b1511e37fa8a4ecc95707d84ed35 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7742", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7742_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7742",
                                     "renesas,rcar-gen2-thermal";
index 2245d19a23bb0a8b0e5b76ed14b59f14a56fb61e..d917c0a971f51b9469f1dde84412d2cb25199aa7 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7743", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7743_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7743",
                                     "renesas,rcar-gen2-thermal";
index aa13841f978149bf0ce09baf6a47eeedad8646db..754859c38a939a9064b207f6fa260eeae67d6388 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7744", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7744_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7744",
                                     "renesas,rcar-gen2-thermal";
index 44688b8431c3f7b32daedac125ae8ca7222388c7..168298300490d31c33191d0d10abeeae27badc16 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7745", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7745_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                ipmmu_sy0: iommu@e6280000 {
                        compatible = "renesas,ipmmu-r8a7745",
                                     "renesas,ipmmu-vmsa";
index a5cf663a0118ee1de0114db7efdd36b231b36180..2375438d83c9d5b656c17da5a0ce85a4194f70a0 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a77470", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
index 46fb81f5062ff6bc6a939ccde667bccdc101e59d..583b74a9f071c39ebbe04257b9794a16c2ed5329 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7790", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7790",
                                     "renesas,rcar-gen2-thermal",
index b9d34147628e120125fe85f451c666cc55442bf1..de08ceb62230b6ddd3f0db92c660f9c66412f673 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7791", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7791",
                                     "renesas,rcar-gen2-thermal",
index ecfab3ff59e843ffa07e94fd12279a4acf5de917..7defeb8e4cd1f499e42ac903ac75f1aa44d4341c 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7792", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7792_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
index f51bf687f4bd55d3e40bbc70fa3601dad9ca45a3..d32a9d5d3faa71fc30cc837cb915a6e418b91be1 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7793", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7793_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                thermal: thermal@e61f0000 {
                        compatible = "renesas,thermal-r8a7793",
                                     "renesas,rcar-gen2-thermal",
index 371dd4715ddef83d9486564a87830e4684a752ea..f37f094cecc8c399204dfb0eccdacd61501a3493 100644 (file)
                        resets = <&cpg 407>;
                };
 
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 125>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+                       resets = <&cpg 125>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@fff60000 {
+                       compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+                       reg = <0 0xfff60000 0 0x30>;
+                       interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 111>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+                       resets = <&cpg 111>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@fff70000 {
+                       compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+                       reg = <0 0xfff70000 0 0x30>;
+                       interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 122>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+                       resets = <&cpg 122>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@fff80000 {
+                       compatible = "renesas,tmu-r8a7794", "renesas,tmu";
+                       reg = <0 0xfff80000 0 0x30>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 121>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A7794_PD_ALWAYS_ON>;
+                       resets = <&cpg 121>;
+                       status = "disabled";
+               };
+
                ipmmu_sy0: iommu@e6280000 {
                        compatible = "renesas,ipmmu-r8a7794",
                                     "renesas,ipmmu-vmsa";
index fa63e1afc4ef4c9201a354f32722d093fd19fd65..45f60eeeaaa1d320fe36bfe997c2bb06cefb8c20 100644 (file)
                gmac2: ethernet@44002000 {
                        compatible = "renesas,r9a06g032-gmac", "renesas,rzn1-gmac", "snps,dwmac";
                        reg = <0x44002000 0x2000>;
-                       interrupt-parent = <&gic>;
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
index 3f1015edab436a5b399f9b2367f6167efc0c494d..b6c3826a942446c35a0a442cc883f5af2f8dadbc 100644 (file)
                        samsung,spi-src-clk = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi0_bus>;
+                       fifo-depth = <256>;
                        status = "disabled";
                };
 
                        samsung,spi-src-clk = <0>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi1_bus>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
index 7f981b5c0d64b5dd445b15e8245517150aed7b1e..ed47d0ce04e12c05fe1b1e9351a91a4aceb58fce 100644 (file)
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi0_bus>;
+                       fifo-depth = <256>;
                        status = "disabled";
                };
 
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi1_bus>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi2_bus>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
index b566f878ed84f9db891c11084d54f48ba096639d..18f4f494093ba84b39b09273517f41e75098842d 100644 (file)
@@ -88,7 +88,7 @@
 &keypad {
        samsung,keypad-num-rows = <2>;
        samsung,keypad-num-columns = <8>;
-       linux,keypad-no-autorepeat;
+       linux,input-no-autorepeat;
        wakeup-source;
        pinctrl-names = "default";
        pinctrl-0 = <&keypad_rows &keypad_cols>;
index e5254e32aa8fc326dfcabce33705a9b25e272052..9bc05961577dca2101418c6ad0ae8e05c76eac61 100644 (file)
                /* Default S-BOOT bootloader loads initramfs here */
                linux,initrd-start = <0x42000000>;
                linux,initrd-end = <0x42800000>;
+
+               /*
+                * Stock bootloader provides incorrect memory size in ATAG_MEM;
+                * override it here
+                */
+               linux,usable-memory-range = <0x40000000 0x3fc00000>;
        };
 
        firmware@204f000 {
index 23b151645d66867f9a9f63d3c935ab4e6b4bcae9..10ab7bc90f502fbac800eb98204a3bbce11e604a 100644 (file)
 &keypad {
        samsung,keypad-num-rows = <3>;
        samsung,keypad-num-columns = <2>;
-       linux,keypad-no-autorepeat;
+       linux,input-no-autorepeat;
        wakeup-source;
        pinctrl-0 = <&keypad_rows &keypad_cols>;
        pinctrl-names = "default";
index 715dfcba14174388f049c33bb72f6738081d15c8..c83fb250e664221a85738485d81a749b1a50aad6 100644 (file)
@@ -69,7 +69,7 @@
 &keypad {
        samsung,keypad-num-rows = <3>;
        samsung,keypad-num-columns = <8>;
-       linux,keypad-no-autorepeat;
+       linux,input-no-autorepeat;
        wakeup-source;
        pinctrl-0 = <&keypad_rows &keypad_cols>;
        pinctrl-names = "default";
                linux,code = <6>;
        };
 
-       key-A {
+       key-a {
                keypad,row = <2>;
                keypad,column = <6>;
                linux,code = <30>;
        };
 
-       key-B {
+       key-b {
                keypad,row = <2>;
                keypad,column = <7>;
                linux,code = <48>;
        };
 
-       key-C {
+       key-c {
                keypad,row = <0>;
                keypad,column = <5>;
                linux,code = <46>;
        };
 
-       key-D {
+       key-d {
                keypad,row = <2>;
                keypad,column = <5>;
                linux,code = <32>;
        };
 
-       key-E {
+       key-e {
                keypad,row = <0>;
                keypad,column = <7>;
                linux,code = <18>;
index 99c84bebf25a4b38cfdf7a65e540ee3ea8af055b..b9e7c493881804647534b1d7395f6eb62a07fb92 100644 (file)
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi0_bus>;
+                       fifo-depth = <256>;
                };
 
                spi_1: spi@12d30000 {
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi1_bus>;
+                       fifo-depth = <64>;
                };
 
                spi_2: spi@12d40000 {
                        clock-names = "spi", "spi_busclk0";
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi2_bus>;
+                       fifo-depth = <64>;
                };
 
                mmc_0: mmc@12200000 {
index 25ed90374679a8ab6ca5e018bbde8ca689ac483f..196c6d04675add4f6ecc0acadac9ef12fa7db602 100644 (file)
                        pinctrl-0 = <&spi0_bus>;
                        clocks = <&clock CLK_SPI0>, <&clock CLK_SCLK_SPI0>;
                        clock-names = "spi", "spi_busclk0";
+                       fifo-depth = <256>;
                        status = "disabled";
                };
 
                        pinctrl-0 = <&spi1_bus>;
                        clocks = <&clock CLK_SPI1>, <&clock CLK_SCLK_SPI1>;
                        clock-names = "spi", "spi_busclk0";
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
                        pinctrl-0 = <&spi2_bus>;
                        clocks = <&clock CLK_SPI2>, <&clock CLK_SCLK_SPI2>;
                        clock-names = "spi", "spi_busclk0";
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
index 9bbbdce9103a66c763e74eb28adb8630ac18228a..bb019868b996eb11eb032f4e95a70bb961f6c48f 100644 (file)
        samsung,color-depth = <1>;
        samsung,link-rate = <0x0a>;
        samsung,lane-count = <2>;
-       samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+       hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>;
 
        ports {
                port {
index ed560c9a3aa1ef30f312c10d90394056dd047ebe..34e8a3d5efa51f911e0a1f3e18035f516303043d 100644 (file)
@@ -72,7 +72,7 @@
                #size-cells = <1>;
                ranges;
 
-               onenand: onenand@b0600000 {
+               onenand: nand-controller@b0600000 {
                        compatible = "samsung,s5pv210-onenand";
                        reg = <0xb0600000 0x2000>,
                                <0xb0000000 0x20000>,
@@ -82,7 +82,7 @@
                        clocks = <&clocks CLK_NANDXL>, <&clocks DOUT_FLASH>;
                        clock-names = "bus", "onenand";
                        #address-cells = <1>;
-                       #size-cells = <1>;
+                       #size-cells = <0>;
                        status = "disabled";
                };
 
                        pinctrl-0 = <&spi0_bus>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       fifo-depth = <256>;
                        status = "disabled";
                };
 
                        pinctrl-0 = <&spi1_bus>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
index 65c72b6fcc8311e66fd9bf03812bd7c98749b904..2537b3d47e6f0ce8e0830d8de08a88a71724a02b 100644 (file)
                        status = "disabled";
                };
 
-               can3: can@40003400 {
-                       compatible = "st,stm32f4-bxcan";
-                       reg = <0x40003400 0x200>;
-                       interrupts = <104>, <105>, <106>, <107>;
-                       interrupt-names = "tx", "rx0", "rx1", "sce";
-                       resets = <&rcc STM32F7_APB1_RESET(CAN3)>;
-                       clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
-                       st,gcan = <&gcan3>;
-                       status = "disabled";
-               };
-
-               gcan3: gcan@40003600 {
-                       compatible = "st,stm32f4-gcan", "syscon";
-                       reg = <0x40003600 0x200>;
-                       clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
-               };
-
                spi2: spi@40003800 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 4e7d9032149c620f1d1beb59ec32b76ba0822fad..e8cbb99e81a6616411c9a65a2ff166753db46c6d 100644 (file)
@@ -7,6 +7,23 @@
 
 / {
        soc {
+               can3: can@40003400 {
+                       compatible = "st,stm32f4-bxcan";
+                       reg = <0x40003400 0x200>;
+                       interrupts = <104>, <105>, <106>, <107>;
+                       interrupt-names = "tx", "rx0", "rx1", "sce";
+                       resets = <&rcc STM32F7_APB1_RESET(CAN3)>;
+                       clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
+                       st,gcan = <&gcan3>;
+                       status = "disabled";
+               };
+
+               gcan3: gcan@40003600 {
+                       compatible = "st,stm32f4-gcan", "syscon";
+                       reg = <0x40003600 0x200>;
+                       clocks = <&rcc 0 STM32F7_APB1_CLOCK(CAN3)>;
+               };
+
                dsi: dsi@40016c00 {
                        compatible = "st,stm32-dsi";
                        reg = <0x40016c00 0x800>;
index 27e0c3826789de645c5cc201444aa5f577d32fa3..32c5d8a1e06acdf0074ab4c6ce0c2e62c80526f0 100644 (file)
                };
        };
 
+       ltdc_pins_a: ltdc-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D',  9, AF13)>, /* LCD_CLK */
+                                <STM32_PINMUX('C',  6, AF14)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('G',  4, AF11)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('H',  9, AF11)>, /* LCD_DE */
+                                <STM32_PINMUX('G',  7, AF14)>, /* LCD_R2 */
+                                <STM32_PINMUX('B', 12, AF13)>, /* LCD_R3 */
+                                <STM32_PINMUX('D', 14, AF14)>, /* LCD_R4 */
+                                <STM32_PINMUX('E',  7, AF14)>, /* LCD_R5 */
+                                <STM32_PINMUX('E', 13, AF14)>, /* LCD_R6 */
+                                <STM32_PINMUX('E',  9, AF14)>, /* LCD_R7 */
+                                <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+                                <STM32_PINMUX('F',  3, AF14)>, /* LCD_G3 */
+                                <STM32_PINMUX('D',  5, AF14)>, /* LCD_G4 */
+                                <STM32_PINMUX('G',  0, AF14)>, /* LCD_G5 */
+                                <STM32_PINMUX('C',  7, AF14)>, /* LCD_G6 */
+                                <STM32_PINMUX('A', 15, AF11)>, /* LCD_G7 */
+                                <STM32_PINMUX('D', 10, AF14)>, /* LCD_B2 */
+                                <STM32_PINMUX('F',  2, AF14)>, /* LCD_B3 */
+                                <STM32_PINMUX('H', 14, AF11)>, /* LCD_B4 */
+                                <STM32_PINMUX('E',  0, AF14)>, /* LCD_B5 */
+                                <STM32_PINMUX('B',  6, AF7)>,  /* LCD_B6 */
+                                <STM32_PINMUX('F',  1, AF13)>; /* LCD_B7 */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       ltdc_sleep_pins_a: ltdc-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_CLK */
+                                <STM32_PINMUX('C',  6, ANALOG)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('G',  4, ANALOG)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_DE */
+                                <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_R2 */
+                                <STM32_PINMUX('B', 12, ANALOG)>, /* LCD_R3 */
+                                <STM32_PINMUX('D', 14, ANALOG)>, /* LCD_R4 */
+                                <STM32_PINMUX('E',  7, ANALOG)>, /* LCD_R5 */
+                                <STM32_PINMUX('E', 13, ANALOG)>, /* LCD_R6 */
+                                <STM32_PINMUX('E',  9, ANALOG)>, /* LCD_R7 */
+                                <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+                                <STM32_PINMUX('F',  3, ANALOG)>, /* LCD_G3 */
+                                <STM32_PINMUX('D',  5, ANALOG)>, /* LCD_G4 */
+                                <STM32_PINMUX('G',  0, ANALOG)>, /* LCD_G5 */
+                                <STM32_PINMUX('C',  7, ANALOG)>, /* LCD_G6 */
+                                <STM32_PINMUX('A', 15, ANALOG)>, /* LCD_G7 */
+                                <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B2 */
+                                <STM32_PINMUX('F',  2, ANALOG)>, /* LCD_B3 */
+                                <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_B4 */
+                                <STM32_PINMUX('E',  0, ANALOG)>, /* LCD_B5 */
+                                <STM32_PINMUX('B',  6, ANALOG)>, /* LCD_B6 */
+                                <STM32_PINMUX('F',  1, ANALOG)>; /* LCD_B7 */
+               };
+       };
+
        mcp23017_pins_a: mcp23017-0 {
                pins {
                        pinmux = <STM32_PINMUX('G', 12, GPIO)>;
index 3900f32da797b4bdfb243d189331c030efead9a6..ecfa120827ba012f275a8ccc9bd512961c8e7359 100644 (file)
                        dma-channels = <16>;
                };
 
-               adc_2: adc@48004000 {
-                       compatible = "st,stm32mp13-adc-core";
-                       reg = <0x48004000 0x400>;
-                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc ADC2>, <&rcc ADC2_K>;
-                       clock-names = "bus", "adc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-
-                       adc2: adc@0 {
-                               compatible = "st,stm32mp13-adc";
-                               #io-channel-cells = <1>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <0x0>;
-                               interrupt-parent = <&adc_2>;
-                               interrupts = <0>;
-                               dmas = <&dmamux1 10 0x400 0x80000001>;
-                               dma-names = "rx";
-                               status = "disabled";
-
-                               channel@13 {
-                                       reg = <13>;
-                                       label = "vrefint";
-                               };
-                               channel@14 {
-                                       reg = <14>;
-                                       label = "vddcore";
-                               };
-                               channel@16 {
-                                       reg = <16>;
-                                       label = "vddcpu";
-                               };
-                               channel@17 {
-                                       reg = <17>;
-                                       label = "vddq_ddr";
-                               };
-                       };
-               };
-
-               usbotg_hs: usb@49000000 {
-                       compatible = "st,stm32mp15-hsotg", "snps,dwc2";
-                       reg = <0x49000000 0x40000>;
-                       clocks = <&rcc USBO_K>;
-                       clock-names = "otg";
-                       resets = <&rcc USBO_R>;
-                       reset-names = "dwc2";
-                       interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-                       g-rx-fifo-size = <512>;
-                       g-np-tx-fifo-size = <32>;
-                       g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
-                       dr_mode = "otg";
-                       otg-rev = <0x200>;
-                       usb33d-supply = <&scmi_usb33>;
-                       status = "disabled";
-               };
-
-               usart1: serial@4c000000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x4c000000 0x400>;
-                       interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART1_K>;
-                       resets = <&rcc USART1_R>;
-                       wakeup-source;
-                       dmas = <&dmamux1 41 0x400 0x5>,
-                              <&dmamux1 42 0x400 0x1>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               usart2: serial@4c001000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x4c001000 0x400>;
-                       interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART2_K>;
-                       resets = <&rcc USART2_R>;
-                       wakeup-source;
-                       dmas = <&dmamux1 43 0x400 0x5>,
-                              <&dmamux1 44 0x400 0x1>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               i2s4: audio-controller@4c002000 {
-                       compatible = "st,stm32h7-i2s";
-                       reg = <0x4c002000 0x400>;
-                       #sound-dai-cells = <0>;
-                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&dmamux1 83 0x400 0x01>,
-                              <&dmamux1 84 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               spi4: spi@4c002000 {
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x4c002000 0x400>;
-                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI4_K>;
-                       resets = <&rcc SPI4_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       dmas = <&dmamux1 83 0x400 0x01>,
-                              <&dmamux1 84 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               spi5: spi@4c003000 {
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x4c003000 0x400>;
-                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI5_K>;
-                       resets = <&rcc SPI5_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       dmas = <&dmamux1 85 0x400 0x01>,
-                              <&dmamux1 86 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               i2c3: i2c@4c004000 {
-                       compatible = "st,stm32mp13-i2c";
-                       reg = <0x4c004000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C3_K>;
-                       resets = <&rcc I2C3_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       dmas = <&dmamux1 73 0x400 0x1>,
-                              <&dmamux1 74 0x400 0x1>;
-                       dma-names = "rx", "tx";
-                       st,syscfg-fmp = <&syscfg 0x4 0x4>;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
-
-               i2c4: i2c@4c005000 {
-                       compatible = "st,stm32mp13-i2c";
-                       reg = <0x4c005000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C4_K>;
-                       resets = <&rcc I2C4_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       dmas = <&dmamux1 75 0x400 0x1>,
-                              <&dmamux1 76 0x400 0x1>;
-                       dma-names = "rx", "tx";
-                       st,syscfg-fmp = <&syscfg 0x4 0x8>;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
-
-               i2c5: i2c@4c006000 {
-                       compatible = "st,stm32mp13-i2c";
-                       reg = <0x4c006000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C5_K>;
-                       resets = <&rcc I2C5_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       dmas = <&dmamux1 115 0x400 0x1>,
-                              <&dmamux1 116 0x400 0x1>;
-                       dma-names = "rx", "tx";
-                       st,syscfg-fmp = <&syscfg 0x4 0x10>;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
-
-               timers12: timer@4c007000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c007000 0x400>;
-                       interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM12_K>;
-                       clock-names = "int";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@11 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <11>;
-                               status = "disabled";
-                       };
-               };
-
-               timers13: timer@4c008000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c008000 0x400>;
-                       interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM13_K>;
-                       clock-names = "int";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@12 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <12>;
-                               status = "disabled";
-                       };
-               };
-
-               timers14: timer@4c009000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c009000 0x400>;
-                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM14_K>;
-                       clock-names = "int";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@13 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <13>;
-                               status = "disabled";
-                       };
-               };
-
-               timers15: timer@4c00a000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c00a000 0x400>;
-                       interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM15_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 105 0x400 0x1>,
-                              <&dmamux1 106 0x400 0x1>,
-                              <&dmamux1 107 0x400 0x1>,
-                              <&dmamux1 108 0x400 0x1>;
-                       dma-names = "ch1", "up", "trig", "com";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@14 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <14>;
-                               status = "disabled";
-                       };
-               };
-
-               timers16: timer@4c00b000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c00b000 0x400>;
-                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM16_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 109 0x400 0x1>,
-                              <&dmamux1 110 0x400 0x1>;
-                       dma-names = "ch1", "up";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@15 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <15>;
-                               status = "disabled";
-                       };
-               };
-
-               timers17: timer@4c00c000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x4c00c000 0x400>;
-                       interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM17_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 111 0x400 0x1>,
-                              <&dmamux1 112 0x400 0x1>;
-                       dma-names = "ch1", "up";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@16 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <16>;
-                               status = "disabled";
-                       };
-               };
-
                rcc: rcc@50000000 {
                        compatible = "st,stm32mp13-rcc", "syscon";
                        reg = <0x50000000 0x1000>;
                                 <&scmi_clk CK_SCMI_LSI>;
                };
 
+               pwr_regulators: pwr@50001000 {
+                       compatible = "st,stm32mp1,pwr-reg";
+                       reg = <0x50001000 0x10>;
+                       status = "disabled";
+
+                       reg11: reg11 {
+                               regulator-name = "reg11";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                       };
+
+                       reg18: reg18 {
+                               regulator-name = "reg18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                       };
+
+                       usb33: usb33 {
+                               regulator-name = "usb33";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+
                exti: interrupt-controller@5000d000 {
                        compatible = "st,stm32mp13-exti", "syscon";
                        interrupt-controller;
                        clocks = <&rcc SYSCFG>;
                };
 
-               lptimer2: timer@50021000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50021000 0x400>;
-                       interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM2_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       trigger@1 {
-                               compatible = "st,stm32-lptimer-trigger";
-                               reg = <1>;
-                               status = "disabled";
-                       };
-
-                       counter {
-                               compatible = "st,stm32-lptimer-counter";
-                               status = "disabled";
-                       };
-
-                       timer {
-                               compatible = "st,stm32-lptimer-timer";
-                               status = "disabled";
-                       };
-               };
-
-               lptimer3: timer@50022000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50022000 0x400>;
-                       interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM3_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       trigger@2 {
-                               compatible = "st,stm32-lptimer-trigger";
-                               reg = <2>;
-                               status = "disabled";
-                       };
-
-                       timer {
-                               compatible = "st,stm32-lptimer-timer";
-                               status = "disabled";
-                       };
-               };
-
                lptimer4: timer@50023000 {
                        compatible = "st,stm32-lptimer";
                        reg = <0x50023000 0x400>;
                        };
                };
 
-               hash: hash@54003000 {
-                       compatible = "st,stm32mp13-hash";
-                       reg = <0x54003000 0x400>;
-                       interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc HASH1>;
-                       resets = <&rcc HASH1_R>;
-                       dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
-                       dma-names = "in";
-                       status = "disabled";
-               };
-
-               rng: rng@54004000 {
-                       compatible = "st,stm32mp13-rng";
-                       reg = <0x54004000 0x400>;
-                       clocks = <&rcc RNG1_K>;
-                       resets = <&rcc RNG1_R>;
-                       status = "disabled";
-               };
-
                mdma: dma-controller@58000000 {
                        compatible = "st,stm32h7-mdma";
                        reg = <0x58000000 0x1000>;
                        dma-requests = <48>;
                };
 
-               fmc: memory-controller@58002000 {
-                       compatible = "st,stm32mp1-fmc2-ebi";
-                       reg = <0x58002000 0x1000>;
-                       ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
-                                <1 0 0x64000000 0x04000000>, /* EBI CS 2 */
-                                <2 0 0x68000000 0x04000000>, /* EBI CS 3 */
-                                <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */
-                                <4 0 0x80000000 0x10000000>; /* NAND */
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-                       clocks = <&rcc FMC_K>;
-                       resets = <&rcc FMC_R>;
-                       status = "disabled";
-
-                       nand-controller@4,0 {
-                               compatible = "st,stm32mp1-fmc2-nfc";
-                               reg = <4 0x00000000 0x1000>,
-                                     <4 0x08010000 0x1000>,
-                                     <4 0x08020000 0x1000>,
-                                     <4 0x01000000 0x1000>,
-                                     <4 0x09010000 0x1000>,
-                                     <4 0x09020000 0x1000>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&mdma 24 0x2 0x12000a02 0x0 0x0>,
-                                      <&mdma 24 0x2 0x12000a08 0x0 0x0>,
-                                      <&mdma 25 0x2 0x12000a0a 0x0 0x0>;
-                               dma-names = "tx", "rx", "ecc";
-                               status = "disabled";
-                       };
-               };
-
-               qspi: spi@58003000 {
-                       compatible = "st,stm32f469-qspi";
-                       reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
-                       reg-names = "qspi", "qspi_mm";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&mdma 26 0x2 0x10100002 0x0 0x0>,
-                              <&mdma 26 0x2 0x10100008 0x0 0x0>;
-                       dma-names = "tx", "rx";
-                       clocks = <&rcc QSPI_K>;
-                       resets = <&rcc QSPI_R>;
-                       status = "disabled";
-               };
-
-               sdmmc1: mmc@58005000 {
-                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-                       arm,primecell-periphid = <0x20253180>;
-                       reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
-                       interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SDMMC1_K>;
-                       clock-names = "apb_pclk";
-                       resets = <&rcc SDMMC1_R>;
-                       cap-sd-highspeed;
-                       cap-mmc-highspeed;
-                       max-frequency = <130000000>;
-                       status = "disabled";
-               };
-
-               sdmmc2: mmc@58007000 {
-                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-                       arm,primecell-periphid = <0x20253180>;
-                       reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
-                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SDMMC2_K>;
-                       clock-names = "apb_pclk";
-                       resets = <&rcc SDMMC2_R>;
-                       cap-sd-highspeed;
-                       cap-mmc-highspeed;
-                       max-frequency = <130000000>;
-                       status = "disabled";
-               };
-
                crc1: crc@58009000 {
                        compatible = "st,stm32f7-crc";
                        reg = <0x58009000 0x400>;
                        status = "disabled";
                };
 
-               usbphyc: usbphyc@5a006000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       #clock-cells = <0>;
-                       compatible = "st,stm32mp1-usbphyc";
-                       reg = <0x5a006000 0x1000>;
-                       clocks = <&rcc USBPHY_K>;
-                       resets = <&rcc USBPHY_R>;
-                       vdda1v1-supply = <&scmi_reg11>;
-                       vdda1v8-supply = <&scmi_reg18>;
-                       status = "disabled";
-
-                       usbphyc_port0: usb-phy@0 {
-                               #phy-cells = <0>;
-                               reg = <0>;
-                       };
-
-                       usbphyc_port1: usb-phy@1 {
-                               #phy-cells = <1>;
-                               reg = <1>;
-                       };
-               };
-
                rtc: rtc@5c004000 {
                        compatible = "st,stm32mp1-rtc";
                        reg = <0x5c004000 0x400>;
                        };
                };
 
+               etzpc: bus@5c007000 {
+                       compatible = "st,stm32-etzpc", "simple-bus";
+                       reg = <0x5c007000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       #access-controller-cells = <1>;
+                       ranges;
+
+                       adc_2: adc@48004000 {
+                               compatible = "st,stm32mp13-adc-core";
+                               reg = <0x48004000 0x400>;
+                               interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc ADC2>, <&rcc ADC2_K>;
+                               clock-names = "bus", "adc";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&etzpc 33>;
+                               status = "disabled";
+
+                               adc2: adc@0 {
+                                       compatible = "st,stm32mp13-adc";
+                                       #io-channel-cells = <1>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0x0>;
+                                       interrupt-parent = <&adc_2>;
+                                       interrupts = <0>;
+                                       dmas = <&dmamux1 10 0x400 0x80000001>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+
+                                       channel@13 {
+                                               reg = <13>;
+                                               label = "vrefint";
+                                       };
+                                       channel@14 {
+                                               reg = <14>;
+                                               label = "vddcore";
+                                       };
+                                       channel@16 {
+                                               reg = <16>;
+                                               label = "vddcpu";
+                                       };
+                                       channel@17 {
+                                               reg = <17>;
+                                               label = "vddq_ddr";
+                                       };
+                               };
+                       };
+
+                       usbotg_hs: usb@49000000 {
+                               compatible = "st,stm32mp15-hsotg", "snps,dwc2";
+                               reg = <0x49000000 0x40000>;
+                               clocks = <&rcc USBO_K>;
+                               clock-names = "otg";
+                               resets = <&rcc USBO_R>;
+                               reset-names = "dwc2";
+                               interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                               g-rx-fifo-size = <512>;
+                               g-np-tx-fifo-size = <32>;
+                               g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
+                               dr_mode = "otg";
+                               otg-rev = <0x200>;
+                               usb33d-supply = <&scmi_usb33>;
+                               access-controllers = <&etzpc 34>;
+                               status = "disabled";
+                       };
+
+                       usart1: serial@4c000000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x4c000000 0x400>;
+                               interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART1_K>;
+                               resets = <&rcc USART1_R>;
+                               wakeup-source;
+                               dmas = <&dmamux1 41 0x400 0x5>,
+                               <&dmamux1 42 0x400 0x1>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 16>;
+                               status = "disabled";
+                       };
+
+                       usart2: serial@4c001000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x4c001000 0x400>;
+                               interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART2_K>;
+                               resets = <&rcc USART2_R>;
+                               wakeup-source;
+                               dmas = <&dmamux1 43 0x400 0x5>,
+                               <&dmamux1 44 0x400 0x1>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 17>;
+                               status = "disabled";
+                       };
+
+                       i2s4: audio-controller@4c002000 {
+                               compatible = "st,stm32h7-i2s";
+                               reg = <0x4c002000 0x400>;
+                               #sound-dai-cells = <0>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 83 0x400 0x01>,
+                               <&dmamux1 84 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 13>;
+                               status = "disabled";
+                       };
+
+                       spi4: spi@4c002000 {
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x4c002000 0x400>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI4_K>;
+                               resets = <&rcc SPI4_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               dmas = <&dmamux1 83 0x400 0x01>,
+                                      <&dmamux1 84 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 18>;
+                               status = "disabled";
+                       };
+
+                       spi5: spi@4c003000 {
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x4c003000 0x400>;
+                               interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI5_K>;
+                               resets = <&rcc SPI5_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               dmas = <&dmamux1 85 0x400 0x01>,
+                                      <&dmamux1 86 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 19>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@4c004000 {
+                               compatible = "st,stm32mp13-i2c";
+                               reg = <0x4c004000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C3_K>;
+                               resets = <&rcc I2C3_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               dmas = <&dmamux1 73 0x400 0x1>,
+                                      <&dmamux1 74 0x400 0x1>;
+                               dma-names = "rx", "tx";
+                               st,syscfg-fmp = <&syscfg 0x4 0x4>;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 20>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@4c005000 {
+                               compatible = "st,stm32mp13-i2c";
+                               reg = <0x4c005000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C4_K>;
+                               resets = <&rcc I2C4_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               dmas = <&dmamux1 75 0x400 0x1>,
+                                      <&dmamux1 76 0x400 0x1>;
+                               dma-names = "rx", "tx";
+                               st,syscfg-fmp = <&syscfg 0x4 0x8>;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 21>;
+                               status = "disabled";
+                       };
+
+                       i2c5: i2c@4c006000 {
+                               compatible = "st,stm32mp13-i2c";
+                               reg = <0x4c006000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C5_K>;
+                               resets = <&rcc I2C5_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               dmas = <&dmamux1 115 0x400 0x1>,
+                                      <&dmamux1 116 0x400 0x1>;
+                               dma-names = "rx", "tx";
+                               st,syscfg-fmp = <&syscfg 0x4 0x10>;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 22>;
+                               status = "disabled";
+                       };
+
+                       timers12: timer@4c007000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c007000 0x400>;
+                               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM12_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 23>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@11 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <11>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       timers13: timer@4c008000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c008000 0x400>;
+                               interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM13_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 24>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@12 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <12>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       timers14: timer@4c009000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c009000 0x400>;
+                               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM14_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 25>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@13 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <13>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       timers15: timer@4c00a000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c00a000 0x400>;
+                               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM15_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 105 0x400 0x1>,
+                               <&dmamux1 106 0x400 0x1>,
+                               <&dmamux1 107 0x400 0x1>,
+                               <&dmamux1 108 0x400 0x1>;
+                               dma-names = "ch1", "up", "trig", "com";
+                               access-controllers = <&etzpc 26>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@14 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <14>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       timers16: timer@4c00b000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c00b000 0x400>;
+                               interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM16_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 109 0x400 0x1>,
+                               <&dmamux1 110 0x400 0x1>;
+                               dma-names = "ch1", "up";
+                               access-controllers = <&etzpc 27>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@15 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <15>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       timers17: timer@4c00c000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x4c00c000 0x400>;
+                               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM17_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 111 0x400 0x1>,
+                                      <&dmamux1 112 0x400 0x1>;
+                               dma-names = "ch1", "up";
+                               access-controllers = <&etzpc 28>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@16 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <16>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       lptimer2: timer@50021000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50021000 0x400>;
+                               interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM2_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 1>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               trigger@1 {
+                                       compatible = "st,stm32-lptimer-trigger";
+                                       reg = <1>;
+                                       status = "disabled";
+                               };
+
+                               counter {
+                                       compatible = "st,stm32-lptimer-counter";
+                                       status = "disabled";
+                               };
+
+                               timer {
+                                       compatible = "st,stm32-lptimer-timer";
+                                       status = "disabled";
+                               };
+                       };
+
+                       lptimer3: timer@50022000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50022000 0x400>;
+                               interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM3_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 2>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               trigger@2 {
+                                       compatible = "st,stm32-lptimer-trigger";
+                                       reg = <2>;
+                                       status = "disabled";
+                               };
+
+                               timer {
+                                       compatible = "st,stm32-lptimer-timer";
+                                       status = "disabled";
+                               };
+                       };
+
+                       hash: hash@54003000 {
+                               compatible = "st,stm32mp13-hash";
+                               reg = <0x54003000 0x400>;
+                               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc HASH1>;
+                               resets = <&rcc HASH1_R>;
+                               dmas = <&mdma 30 0x2 0x1000a02 0x0 0x0>;
+                               dma-names = "in";
+                               access-controllers = <&etzpc 41>;
+                               status = "disabled";
+                       };
+
+                       rng: rng@54004000 {
+                               compatible = "st,stm32mp13-rng";
+                               reg = <0x54004000 0x400>;
+                               clocks = <&rcc RNG1_K>;
+                               resets = <&rcc RNG1_R>;
+                               access-controllers = <&etzpc 40>;
+                               status = "disabled";
+                       };
+
+                       fmc: memory-controller@58002000 {
+                               compatible = "st,stm32mp1-fmc2-ebi";
+                               reg = <0x58002000 0x1000>;
+                               ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
+                                        <1 0 0x64000000 0x04000000>, /* EBI CS 2 */
+                                        <2 0 0x68000000 0x04000000>, /* EBI CS 3 */
+                                        <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */
+                                        <4 0 0x80000000 0x10000000>; /* NAND */
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               clocks = <&rcc FMC_K>;
+                               resets = <&rcc FMC_R>;
+                               access-controllers = <&etzpc 54>;
+                               status = "disabled";
+
+                               nand-controller@4,0 {
+                                       compatible = "st,stm32mp1-fmc2-nfc";
+                                       reg = <4 0x00000000 0x1000>,
+                                             <4 0x08010000 0x1000>,
+                                             <4 0x08020000 0x1000>,
+                                             <4 0x01000000 0x1000>,
+                                             <4 0x09010000 0x1000>,
+                                             <4 0x09020000 0x1000>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&mdma 24 0x2 0x12000a02 0x0 0x0>,
+                                              <&mdma 24 0x2 0x12000a08 0x0 0x0>,
+                                              <&mdma 25 0x2 0x12000a0a 0x0 0x0>;
+                                       dma-names = "tx", "rx", "ecc";
+                                       status = "disabled";
+                               };
+                       };
+
+                       qspi: spi@58003000 {
+                               compatible = "st,stm32f469-qspi";
+                               reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+                               reg-names = "qspi", "qspi_mm";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&mdma 26 0x2 0x10100002 0x0 0x0>,
+                                      <&mdma 26 0x2 0x10100008 0x0 0x0>;
+                               dma-names = "tx", "rx";
+                               clocks = <&rcc QSPI_K>;
+                               resets = <&rcc QSPI_R>;
+                               access-controllers = <&etzpc 55>;
+                               status = "disabled";
+                       };
+
+                       sdmmc1: mmc@58005000 {
+                               compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+                               arm,primecell-periphid = <0x20253180>;
+                               reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
+                               interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SDMMC1_K>;
+                               clock-names = "apb_pclk";
+                               resets = <&rcc SDMMC1_R>;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               max-frequency = <130000000>;
+                               access-controllers = <&etzpc 50>;
+                               status = "disabled";
+                       };
+
+                       sdmmc2: mmc@58007000 {
+                               compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+                               arm,primecell-periphid = <0x20253180>;
+                               reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+                               interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SDMMC2_K>;
+                               clock-names = "apb_pclk";
+                               resets = <&rcc SDMMC2_R>;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               max-frequency = <130000000>;
+                               access-controllers = <&etzpc 51>;
+                               status = "disabled";
+                       };
+
+                       usbphyc: usbphyc@5a006000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #clock-cells = <0>;
+                               compatible = "st,stm32mp1-usbphyc";
+                               reg = <0x5a006000 0x1000>;
+                               clocks = <&rcc USBPHY_K>;
+                               resets = <&rcc USBPHY_R>;
+                               vdda1v1-supply = <&scmi_reg11>;
+                               vdda1v8-supply = <&scmi_reg18>;
+                               access-controllers = <&etzpc 5>;
+                               status = "disabled";
+
+                               usbphyc_port0: usb-phy@0 {
+                                       #phy-cells = <0>;
+                                       reg = <0>;
+                               };
+
+                               usbphyc_port1: usb-phy@1 {
+                                       #phy-cells = <1>;
+                                       reg = <1>;
+                               };
+                       };
+               };
+
                /*
                 * Break node order to solve dependency probe issue between
                 * pinctrl and exti.
index df451c3c2a26d77ec141e1cfb68d12b38886dd36..3e394c8e58b9239e83574bd4e254cb3c253dc3e4 100644 (file)
                        bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
                        status = "disabled";
                };
+       };
+};
 
-               adc_1: adc@48003000 {
-                       compatible = "st,stm32mp13-adc-core";
-                       reg = <0x48003000 0x400>;
-                       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc ADC1>, <&rcc ADC1_K>;
-                       clock-names = "bus", "adc";
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
+&etzpc {
+       adc_1: adc@48003000 {
+               compatible = "st,stm32mp13-adc-core";
+               reg = <0x48003000 0x400>;
+               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&rcc ADC1>, <&rcc ADC1_K>;
+               clock-names = "bus", "adc";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               access-controllers = <&etzpc 32>;
+               status = "disabled";
+
+               adc1: adc@0 {
+                       compatible = "st,stm32mp13-adc";
+                       #io-channel-cells = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       reg = <0x0>;
+                       interrupt-parent = <&adc_1>;
+                       interrupts = <0>;
+                       dmas = <&dmamux1 9 0x400 0x80000001>;
+                       dma-names = "rx";
                        status = "disabled";
 
-                       adc1: adc@0 {
-                               compatible = "st,stm32mp13-adc";
-                               #io-channel-cells = <1>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <0x0>;
-                               interrupt-parent = <&adc_1>;
-                               interrupts = <0>;
-                               dmas = <&dmamux1 9 0x400 0x80000001>;
-                               dma-names = "rx";
-                               status = "disabled";
-
-                               channel@18 {
-                                       reg = <18>;
-                                       label = "vrefint";
-                               };
+                       channel@18 {
+                               reg = <18>;
+                               label = "vrefint";
                        };
                };
        };
index 68d32f9f5314a686ac9fece344486d5a7d49aea5..834a4d545fe448c15feea3a3acd169da1da73e91 100644 (file)
                        port {
                        };
                };
+
+               ltdc: display-controller@5a001000 {
+                       compatible = "st,stm32-ltdc";
+                       reg = <0x5a001000 0x400>;
+                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc LTDC_PX>;
+                       clock-names = "lcd";
+                       resets = <&scmi_reset RST_SCMI_LTDC>;
+                       status = "disabled";
+               };
        };
 };
index 52171214a3087d29c275986971a38764a278a98a..567e53ad285fab1a1c508f28a22c1f385bd099da 100644 (file)
                        default-state = "off";
                };
        };
+
+       panel_backlight: panel-backlight {
+               compatible = "gpio-backlight";
+               gpios = <&gpioe 12 GPIO_ACTIVE_HIGH>;
+               default-on;
+               status = "okay";
+       };
+
+       panel_rgb: panel-rgb {
+               compatible = "rocktech,rk043fn48h";
+               enable-gpios = <&gpioi 7 GPIO_ACTIVE_HIGH>;
+               backlight = <&panel_backlight>;
+               power-supply = <&scmi_v3v3_sw>;
+               status = "okay";
+
+               width-mm = <105>;
+               height-mm = <67>;
+
+               panel-timing {
+                       clock-frequency = <10000000>;
+                       hactive = <480>;
+                       hback-porch = <43>;
+                       hfront-porch = <10>;
+                       hsync-len = <1>;
+                       hsync-active = <0>;
+                       vactive = <272>;
+                       vback-porch = <26>;
+                       vfront-porch = <4>;
+                       vsync-len = <10>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+
+               port {
+                       panel_in_rgb: endpoint {
+                               remote-endpoint = <&ltdc_out_rgb>;
+                       };
+               };
+       };
 };
 
 &adc_1 {
        status = "okay";
 };
 
+&ltdc {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&ltdc_pins_a>;
+       pinctrl-1 = <&ltdc_sleep_pins_a>;
+       status = "okay";
+
+       port {
+               ltdc_out_rgb: endpoint {
+                       remote-endpoint = <&panel_in_rgb>;
+               };
+       };
+};
+
 &rtc {
        status = "okay";
 };
index 4d00e759288291ef02e57b48d5525023c0000822..a8bd5fe6536c8cf631964aeec7fe5fd6ce03fe98 100644 (file)
@@ -4,15 +4,14 @@
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
-/ {
-       soc {
-               cryp: crypto@54002000 {
-                       compatible = "st,stm32mp1-cryp";
-                       reg = <0x54002000 0x400>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc CRYP1>;
-                       resets = <&rcc CRYP1_R>;
-                       status = "disabled";
-               };
+&etzpc {
+       cryp: crypto@54002000 {
+               compatible = "st,stm32mp1-cryp";
+               reg = <0x54002000 0x400>;
+               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&rcc CRYP1>;
+               resets = <&rcc CRYP1_R>;
+               access-controllers = <&etzpc 42>;
+               status = "disabled";
        };
 };
index 4d00e759288291ef02e57b48d5525023c0000822..a8bd5fe6536c8cf631964aeec7fe5fd6ce03fe98 100644 (file)
@@ -4,15 +4,14 @@
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
 
-/ {
-       soc {
-               cryp: crypto@54002000 {
-                       compatible = "st,stm32mp1-cryp";
-                       reg = <0x54002000 0x400>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc CRYP1>;
-                       resets = <&rcc CRYP1_R>;
-                       status = "disabled";
-               };
+&etzpc {
+       cryp: crypto@54002000 {
+               compatible = "st,stm32mp1-cryp";
+               reg = <0x54002000 0x400>;
+               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&rcc CRYP1>;
+               resets = <&rcc CRYP1_R>;
+               access-controllers = <&etzpc 42>;
+               status = "disabled";
        };
 };
index fa4cbd312e5a1119543d47d4811afc3ff80a642d..16bd6eee32b4e24d5b2f1ce99cab743c0b69e2ba 100644 (file)
                interrupt-parent = <&intc>;
                ranges;
 
-               timers2: timer@40000000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40000000 0x400>;
-                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM2_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 18 0x400 0x1>,
-                              <&dmamux1 19 0x400 0x1>,
-                              <&dmamux1 20 0x400 0x1>,
-                              <&dmamux1 21 0x400 0x1>,
-                              <&dmamux1 22 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4", "up";
+               ipcc: mailbox@4c001000 {
+                       compatible = "st,stm32mp1-ipcc";
+                       #mbox-cells = <1>;
+                       reg = <0x4c001000 0x400>;
+                       st,proc-id = <0>;
+                       interrupts-extended =
+                               <&exti 61 1>,
+                               <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "rx", "tx";
+                       clocks = <&rcc IPCC>;
+                       wakeup-source;
                        status = "disabled";
+               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@1 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <1>;
-                               status = "disabled";
-                       };
-
-                       counter {
-                               compatible = "st,stm32-timer-counter";
-                               status = "disabled";
-                       };
+               rcc: rcc@50000000 {
+                       compatible = "st,stm32mp1-rcc", "syscon";
+                       reg = <0x50000000 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
                };
 
-               timers3: timer@40001000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40001000 0x400>;
-                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM3_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 23 0x400 0x1>,
-                              <&dmamux1 24 0x400 0x1>,
-                              <&dmamux1 25 0x400 0x1>,
-                              <&dmamux1 26 0x400 0x1>,
-                              <&dmamux1 27 0x400 0x1>,
-                              <&dmamux1 28 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
-                       status = "disabled";
+               pwr_regulators: pwr@50001000 {
+                       compatible = "st,stm32mp1,pwr-reg";
+                       reg = <0x50001000 0x10>;
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
+                       reg11: reg11 {
+                               regulator-name = "reg11";
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
                        };
 
-                       timer@2 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <2>;
-                               status = "disabled";
+                       reg18: reg18 {
+                               regulator-name = "reg18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
                        };
 
-                       counter {
-                               compatible = "st,stm32-timer-counter";
-                               status = "disabled";
+                       usb33: usb33 {
+                               regulator-name = "usb33";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
                        };
                };
 
-               timers4: timer@40002000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40002000 0x400>;
-                       interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM4_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 29 0x400 0x1>,
-                              <&dmamux1 30 0x400 0x1>,
-                              <&dmamux1 31 0x400 0x1>,
-                              <&dmamux1 32 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4";
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
+               pwr_mcu: pwr_mcu@50001014 {
+                       compatible = "st,stm32mp151-pwr-mcu", "syscon";
+                       reg = <0x50001014 0x4>;
+               };
 
-                       timer@3 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <3>;
-                               status = "disabled";
-                       };
+               exti: interrupt-controller@5000d000 {
+                       compatible = "st,stm32mp1-exti", "syscon";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       reg = <0x5000d000 0x400>;
+               };
 
-                       counter {
-                               compatible = "st,stm32-timer-counter";
-                               status = "disabled";
-                       };
+               syscfg: syscon@50020000 {
+                       compatible = "st,stm32mp157-syscfg", "syscon";
+                       reg = <0x50020000 0x400>;
+                       clocks = <&rcc SYSCFG>;
                };
 
-               timers5: timer@40003000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40003000 0x400>;
-                       interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM5_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 55 0x400 0x1>,
-                              <&dmamux1 56 0x400 0x1>,
-                              <&dmamux1 57 0x400 0x1>,
-                              <&dmamux1 58 0x400 0x1>,
-                              <&dmamux1 59 0x400 0x1>,
-                              <&dmamux1 60 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+               dts: thermal@50028000 {
+                       compatible = "st,stm32-thermal";
+                       reg = <0x50028000 0x100>;
+                       interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc TMPSENS>;
+                       clock-names = "pclk";
+                       #thermal-sensor-cells = <0>;
                        status = "disabled";
+               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@4 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <4>;
-                               status = "disabled";
-                       };
-
-                       counter {
-                               compatible = "st,stm32-timer-counter";
-                               status = "disabled";
-                       };
+               mdma1: dma-controller@58000000 {
+                       compatible = "st,stm32h7-mdma";
+                       reg = <0x58000000 0x1000>;
+                       interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc MDMA>;
+                       resets = <&rcc MDMA_R>;
+                       #dma-cells = <5>;
+                       dma-channels = <32>;
+                       dma-requests = <48>;
                };
 
-               timers6: timer@40004000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40004000 0x400>;
-                       interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM6_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 69 0x400 0x1>;
-                       dma-names = "up";
+               sdmmc1: mmc@58005000 {
+                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+                       arm,primecell-periphid = <0x00253180>;
+                       reg = <0x58005000 0x1000>;
+                       interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SDMMC1_K>;
+                       clock-names = "apb_pclk";
+                       resets = <&rcc SDMMC1_R>;
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       max-frequency = <120000000>;
                        status = "disabled";
-
-                       timer@5 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <5>;
-                               status = "disabled";
-                       };
                };
 
-               timers7: timer@40005000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40005000 0x400>;
-                       interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM7_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 70 0x400 0x1>;
-                       dma-names = "up";
+               sdmmc2: mmc@58007000 {
+                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+                       arm,primecell-periphid = <0x00253180>;
+                       reg = <0x58007000 0x1000>;
+                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc SDMMC2_K>;
+                       clock-names = "apb_pclk";
+                       resets = <&rcc SDMMC2_R>;
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       max-frequency = <120000000>;
                        status = "disabled";
-
-                       timer@6 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <6>;
-                               status = "disabled";
-                       };
                };
 
-               timers12: timer@40006000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40006000 0x400>;
-                       interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM12_K>;
-                       clock-names = "int";
+               crc1: crc@58009000 {
+                       compatible = "st,stm32f7-crc";
+                       reg = <0x58009000 0x400>;
+                       clocks = <&rcc CRC1>;
                        status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@11 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <11>;
-                               status = "disabled";
-                       };
                };
 
-               timers13: timer@40007000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40007000 0x400>;
-                       interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM13_K>;
-                       clock-names = "int";
+               usbh_ohci: usb@5800c000 {
+                       compatible = "generic-ohci";
+                       reg = <0x5800c000 0x1000>;
+                       clocks = <&usbphyc>, <&rcc USBH>;
+                       resets = <&rcc USBH_R>;
+                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+                       phys = <&usbphyc_port0>;
+                       phy-names = "usb";
                        status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       timer@12 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <12>;
-                               status = "disabled";
-                       };
                };
 
-               timers14: timer@40008000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x40008000 0x400>;
-                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM14_K>;
-                       clock-names = "int";
+               usbh_ehci: usb@5800d000 {
+                       compatible = "generic-ehci";
+                       reg = <0x5800d000 0x1000>;
+                       clocks = <&usbphyc>, <&rcc USBH>;
+                       resets = <&rcc USBH_R>;
+                       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+                       companion = <&usbh_ohci>;
+                       phys = <&usbphyc_port0>;
+                       phy-names = "usb";
                        status = "disabled";
+               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
+               ltdc: display-controller@5a001000 {
+                       compatible = "st,stm32-ltdc";
+                       reg = <0x5a001000 0x400>;
+                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc LTDC_PX>;
+                       clock-names = "lcd";
+                       resets = <&rcc LTDC_R>;
+                       status = "disabled";
+               };
 
-                       timer@13 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <13>;
-                               status = "disabled";
-                       };
+               iwdg2: watchdog@5a002000 {
+                       compatible = "st,stm32mp1-iwdg";
+                       reg = <0x5a002000 0x400>;
+                       clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+                       clock-names = "pclk", "lsi";
+                       status = "disabled";
                };
 
-               lptimer1: timer@40009000 {
+               usbphyc: usbphyc@5a006000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x40009000 0x400>;
-                       interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM1_K>;
-                       clock-names = "mux";
-                       wakeup-source;
+                       #clock-cells = <0>;
+                       compatible = "st,stm32mp1-usbphyc";
+                       reg = <0x5a006000 0x1000>;
+                       clocks = <&rcc USBPHY_K>;
+                       resets = <&rcc USBPHY_R>;
+                       vdda1v1-supply = <&reg11>;
+                       vdda1v8-supply = <&reg18>;
                        status = "disabled";
 
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       trigger@0 {
-                               compatible = "st,stm32-lptimer-trigger";
+                       usbphyc_port0: usb-phy@0 {
+                               #phy-cells = <0>;
                                reg = <0>;
-                               status = "disabled";
                        };
 
-                       counter {
-                               compatible = "st,stm32-lptimer-counter";
-                               status = "disabled";
+                       usbphyc_port1: usb-phy@1 {
+                               #phy-cells = <1>;
+                               reg = <1>;
                        };
                };
 
-               spi2: spi@4000b000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x4000b000 0x400>;
-                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI2_K>;
-                       resets = <&rcc SPI2_R>;
-                       dmas = <&dmamux1 39 0x400 0x05>,
-                              <&dmamux1 40 0x400 0x05>;
-                       dma-names = "rx", "tx";
+               rtc: rtc@5c004000 {
+                       compatible = "st,stm32mp1-rtc";
+                       reg = <0x5c004000 0x400>;
+                       clocks = <&rcc RTCAPB>, <&rcc RTC>;
+                       clock-names = "pclk", "rtc_ck";
+                       interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               i2s2: audio-controller@4000b000 {
-                       compatible = "st,stm32h7-i2s";
-                       #sound-dai-cells = <0>;
-                       reg = <0x4000b000 0x400>;
-                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&dmamux1 39 0x400 0x01>,
-                              <&dmamux1 40 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
+               bsec: efuse@5c005000 {
+                       compatible = "st,stm32mp15-bsec";
+                       reg = <0x5c005000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       part_number_otp: part-number-otp@4 {
+                               reg = <0x4 0x1>;
+                       };
+                       vrefint: vrefin-cal@52 {
+                               reg = <0x52 0x2>;
+                       };
+                       ts_cal1: calib@5c {
+                               reg = <0x5c 0x2>;
+                       };
+                       ts_cal2: calib@5e {
+                               reg = <0x5e 0x2>;
+                       };
                };
 
-               spi3: spi@4000c000 {
+               etzpc: bus@5c007000 {
+                       compatible = "st,stm32-etzpc", "simple-bus";
+                       reg = <0x5c007000 0x400>;
                        #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x4000c000 0x400>;
-                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI3_K>;
-                       resets = <&rcc SPI3_R>;
-                       dmas = <&dmamux1 61 0x400 0x05>,
-                              <&dmamux1 62 0x400 0x05>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                       #size-cells = <1>;
+                       #access-controller-cells = <1>;
+                       ranges;
 
-               i2s3: audio-controller@4000c000 {
-                       compatible = "st,stm32h7-i2s";
-                       #sound-dai-cells = <0>;
-                       reg = <0x4000c000 0x400>;
-                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&dmamux1 61 0x400 0x01>,
-                              <&dmamux1 62 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                       timers2: timer@40000000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40000000 0x400>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM2_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 18 0x400 0x1>,
+                                      <&dmamux1 19 0x400 0x1>,
+                                      <&dmamux1 20 0x400 0x1>,
+                                      <&dmamux1 21 0x400 0x1>,
+                                      <&dmamux1 22 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4", "up";
+                               access-controllers = <&etzpc 16>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               spdifrx: audio-controller@4000d000 {
-                       compatible = "st,stm32h7-spdifrx";
-                       #sound-dai-cells = <0>;
-                       reg = <0x4000d000 0x400>;
-                       clocks = <&rcc SPDIF_K>;
-                       clock-names = "kclk";
-                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&dmamux1 93 0x400 0x01>,
-                              <&dmamux1 94 0x400 0x01>;
-                       dma-names = "rx", "rx-ctrl";
-                       status = "disabled";
-               };
+                               timer@1 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <1>;
+                                       status = "disabled";
+                               };
 
-               usart2: serial@4000e000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x4000e000 0x400>;
-                       interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART2_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 43 0x400 0x15>,
-                              <&dmamux1 44 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
+                       };
 
-               usart3: serial@4000f000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x4000f000 0x400>;
-                       interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART3_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 45 0x400 0x15>,
-                              <&dmamux1 46 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                       timers3: timer@40001000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40001000 0x400>;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM3_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 23 0x400 0x1>,
+                                      <&dmamux1 24 0x400 0x1>,
+                                      <&dmamux1 25 0x400 0x1>,
+                                      <&dmamux1 26 0x400 0x1>,
+                                      <&dmamux1 27 0x400 0x1>,
+                                      <&dmamux1 28 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+                               access-controllers = <&etzpc 17>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               uart4: serial@40010000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x40010000 0x400>;
-                       interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc UART4_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 63 0x400 0x15>,
-                              <&dmamux1 64 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                               timer@2 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <2>;
+                                       status = "disabled";
+                               };
 
-               uart5: serial@40011000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x40011000 0x400>;
-                       interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc UART5_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 65 0x400 0x15>,
-                              <&dmamux1 66 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
+                       };
 
-               i2c1: i2c@40012000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x40012000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C1_K>;
-                       resets = <&rcc I2C1_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x1>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
+                       timers4: timer@40002000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40002000 0x400>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM4_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 29 0x400 0x1>,
+                                      <&dmamux1 30 0x400 0x1>,
+                                      <&dmamux1 31 0x400 0x1>,
+                                      <&dmamux1 32 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4";
+                               access-controllers = <&etzpc 18>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               i2c2: i2c@40013000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x40013000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C2_K>;
-                       resets = <&rcc I2C2_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x2>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
+                               timer@3 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <3>;
+                                       status = "disabled";
+                               };
 
-               i2c3: i2c@40014000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x40014000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C3_K>;
-                       resets = <&rcc I2C3_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x4>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
+                       };
 
-               i2c5: i2c@40015000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x40015000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C5_K>;
-                       resets = <&rcc I2C5_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x10>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
+                       timers5: timer@40003000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40003000 0x400>;
+                               interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM5_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 55 0x400 0x1>,
+                                      <&dmamux1 56 0x400 0x1>,
+                                      <&dmamux1 57 0x400 0x1>,
+                                      <&dmamux1 58 0x400 0x1>,
+                                      <&dmamux1 59 0x400 0x1>,
+                                      <&dmamux1 60 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4", "up", "trig";
+                               access-controllers = <&etzpc 19>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               cec: cec@40016000 {
-                       compatible = "st,stm32-cec";
-                       reg = <0x40016000 0x400>;
-                       interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc CEC_K>, <&rcc CEC>;
-                       clock-names = "cec", "hdmi-cec";
-                       status = "disabled";
-               };
+                               timer@4 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <4>;
+                                       status = "disabled";
+                               };
 
-               dac: dac@40017000 {
-                       compatible = "st,stm32h7-dac-core";
-                       reg = <0x40017000 0x400>;
-                       clocks = <&rcc DAC12>;
-                       clock-names = "pclk";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
+                       };
 
-                       dac1: dac@1 {
-                               compatible = "st,stm32-dac";
-                               #io-channel-cells = <1>;
-                               reg = <1>;
-                               status = "disabled";
+                       timers6: timer@40004000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40004000 0x400>;
+                               interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM6_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 69 0x400 0x1>;
+                               dma-names = "up";
+                               access-controllers = <&etzpc 20>;
+                               status = "disabled";
+
+                               timer@5 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <5>;
+                                       status = "disabled";
+                               };
                        };
 
-                       dac2: dac@2 {
-                               compatible = "st,stm32-dac";
-                               #io-channel-cells = <1>;
-                               reg = <2>;
-                               status = "disabled";
+                       timers7: timer@40005000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40005000 0x400>;
+                               interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM7_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 70 0x400 0x1>;
+                               dma-names = "up";
+                               access-controllers = <&etzpc 21>;
+                               status = "disabled";
+
+                               timer@6 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <6>;
+                                       status = "disabled";
+                               };
                        };
-               };
 
-               uart7: serial@40018000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x40018000 0x400>;
-                       interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc UART7_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 79 0x400 0x15>,
-                              <&dmamux1 80 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                       timers12: timer@40006000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40006000 0x400>;
+                               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM12_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 22>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               uart8: serial@40019000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x40019000 0x400>;
-                       interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc UART8_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 81 0x400 0x15>,
-                              <&dmamux1 82 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                               timer@11 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <11>;
+                                       status = "disabled";
+                               };
+                       };
 
-               timers1: timer@44000000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x44000000 0x400>;
-                       interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "brk", "up", "trg-com", "cc";
-                       clocks = <&rcc TIM1_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 11 0x400 0x1>,
-                              <&dmamux1 12 0x400 0x1>,
-                              <&dmamux1 13 0x400 0x1>,
-                              <&dmamux1 14 0x400 0x1>,
-                              <&dmamux1 15 0x400 0x1>,
-                              <&dmamux1 16 0x400 0x1>,
-                              <&dmamux1 17 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4",
-                                   "up", "trig", "com";
-                       status = "disabled";
+                       timers13: timer@40007000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40007000 0x400>;
+                               interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM13_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 23>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
+                               timer@12 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <12>;
+                                       status = "disabled";
+                               };
                        };
 
-                       timer@0 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <0>;
-                               status = "disabled";
-                       };
+                       timers14: timer@40008000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x40008000 0x400>;
+                               interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM14_K>;
+                               clock-names = "int";
+                               access-controllers = <&etzpc 24>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       counter {
-                               compatible = "st,stm32-timer-counter";
-                               status = "disabled";
+                               timer@13 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <13>;
+                                       status = "disabled";
+                               };
                        };
-               };
 
-               timers8: timer@44001000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x44001000 0x400>;
-                       interrupts = <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>;
-                       interrupt-names = "brk", "up", "trg-com", "cc";
-                       clocks = <&rcc TIM8_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 47 0x400 0x1>,
-                              <&dmamux1 48 0x400 0x1>,
-                              <&dmamux1 49 0x400 0x1>,
-                              <&dmamux1 50 0x400 0x1>,
-                              <&dmamux1 51 0x400 0x1>,
-                              <&dmamux1 52 0x400 0x1>,
-                              <&dmamux1 53 0x400 0x1>;
-                       dma-names = "ch1", "ch2", "ch3", "ch4",
-                                   "up", "trig", "com";
-                       status = "disabled";
+                       lptimer1: timer@40009000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x40009000 0x400>;
+                               interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM1_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 25>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
-                               status = "disabled";
+                               trigger@0 {
+                                       compatible = "st,stm32-lptimer-trigger";
+                                       reg = <0>;
+                                       status = "disabled";
+                               };
+
+                               counter {
+                                       compatible = "st,stm32-lptimer-counter";
+                                       status = "disabled";
+                               };
                        };
 
-                       timer@7 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <7>;
+                       i2s2: audio-controller@4000b000 {
+                               compatible = "st,stm32h7-i2s";
+                               #sound-dai-cells = <0>;
+                               reg = <0x4000b000 0x400>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 39 0x400 0x01>,
+                                      <&dmamux1 40 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 27>;
                                status = "disabled";
                        };
 
-                       counter {
-                               compatible = "st,stm32-timer-counter";
+                       spi2: spi@4000b000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x4000b000 0x400>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI2_K>;
+                               resets = <&rcc SPI2_R>;
+                               dmas = <&dmamux1 39 0x400 0x05>,
+                                      <&dmamux1 40 0x400 0x05>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 27>;
                                status = "disabled";
                        };
-               };
-
-               usart6: serial@44003000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x44003000 0x400>;
-                       interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART6_K>;
-                       wakeup-source;
-                       dmas = <&dmamux1 71 0x400 0x15>,
-                              <&dmamux1 72 0x400 0x11>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               spi1: spi@44004000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x44004000 0x400>;
-                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI1_K>;
-                       resets = <&rcc SPI1_R>;
-                       dmas = <&dmamux1 37 0x400 0x05>,
-                              <&dmamux1 38 0x400 0x05>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               i2s1: audio-controller@44004000 {
-                       compatible = "st,stm32h7-i2s";
-                       #sound-dai-cells = <0>;
-                       reg = <0x44004000 0x400>;
-                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&dmamux1 37 0x400 0x01>,
-                              <&dmamux1 38 0x400 0x01>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               spi4: spi@44005000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x44005000 0x400>;
-                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI4_K>;
-                       resets = <&rcc SPI4_R>;
-                       dmas = <&dmamux1 83 0x400 0x05>,
-                              <&dmamux1 84 0x400 0x05>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               timers15: timer@44006000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x44006000 0x400>;
-                       interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM15_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 105 0x400 0x1>,
-                              <&dmamux1 106 0x400 0x1>,
-                              <&dmamux1 107 0x400 0x1>,
-                              <&dmamux1 108 0x400 0x1>;
-                       dma-names = "ch1", "up", "trig", "com";
-                       status = "disabled";
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
+                       i2s3: audio-controller@4000c000 {
+                               compatible = "st,stm32h7-i2s";
+                               #sound-dai-cells = <0>;
+                               reg = <0x4000c000 0x400>;
+                               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 61 0x400 0x01>,
+                                      <&dmamux1 62 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 28>;
                                status = "disabled";
                        };
 
-                       timer@14 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <14>;
+                       spi3: spi@4000c000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x4000c000 0x400>;
+                               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI3_K>;
+                               resets = <&rcc SPI3_R>;
+                               dmas = <&dmamux1 61 0x400 0x05>,
+                                      <&dmamux1 62 0x400 0x05>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 28>;
                                status = "disabled";
                        };
-               };
-
-               timers16: timer@44007000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x44007000 0x400>;
-                       interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM16_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 109 0x400 0x1>,
-                              <&dmamux1 110 0x400 0x1>;
-                       dma-names = "ch1", "up";
-                       status = "disabled";
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
+                       spdifrx: audio-controller@4000d000 {
+                               compatible = "st,stm32h7-spdifrx";
+                               #sound-dai-cells = <0>;
+                               reg = <0x4000d000 0x400>;
+                               clocks = <&rcc SPDIF_K>;
+                               clock-names = "kclk";
+                               interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 93 0x400 0x01>,
+                                      <&dmamux1 94 0x400 0x01>;
+                               dma-names = "rx", "rx-ctrl";
+                               access-controllers = <&etzpc 29>;
+                               status = "disabled";
+                       };
+
+                       usart2: serial@4000e000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x4000e000 0x400>;
+                               interrupts-extended = <&exti 27 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART2_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 43 0x400 0x15>,
+                                      <&dmamux1 44 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 30>;
+                               status = "disabled";
+                       };
+
+                       usart3: serial@4000f000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x4000f000 0x400>;
+                               interrupts-extended = <&exti 28 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART3_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 45 0x400 0x15>,
+                                      <&dmamux1 46 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 31>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@40010000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x40010000 0x400>;
+                               interrupts-extended = <&exti 30 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc UART4_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 63 0x400 0x15>,
+                                      <&dmamux1 64 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 32>;
+                               status = "disabled";
+                       };
+
+                       uart5: serial@40011000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x40011000 0x400>;
+                               interrupts-extended = <&exti 31 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc UART5_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 65 0x400 0x15>,
+                                      <&dmamux1 66 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 33>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@40012000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x40012000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C1_K>;
+                               resets = <&rcc I2C1_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               st,syscfg-fmp = <&syscfg 0x4 0x1>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 34>;
                                status = "disabled";
                        };
-                       timer@15 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <15>;
+
+                       i2c2: i2c@40013000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x40013000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C2_K>;
+                               resets = <&rcc I2C2_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               st,syscfg-fmp = <&syscfg 0x4 0x2>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 35>;
                                status = "disabled";
                        };
-               };
 
-               timers17: timer@44008000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-timers";
-                       reg = <0x44008000 0x400>;
-                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "global";
-                       clocks = <&rcc TIM17_K>;
-                       clock-names = "int";
-                       dmas = <&dmamux1 111 0x400 0x1>,
-                              <&dmamux1 112 0x400 0x1>;
-                       dma-names = "ch1", "up";
-                       status = "disabled";
+                       i2c3: i2c@40014000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x40014000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C3_K>;
+                               resets = <&rcc I2C3_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               st,syscfg-fmp = <&syscfg 0x4 0x4>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 36>;
+                               status = "disabled";
+                       };
 
-                       pwm {
-                               compatible = "st,stm32-pwm";
-                               #pwm-cells = <3>;
+                       i2c5: i2c@40015000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x40015000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C5_K>;
+                               resets = <&rcc I2C5_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               st,syscfg-fmp = <&syscfg 0x4 0x10>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 37>;
                                status = "disabled";
                        };
 
-                       timer@16 {
-                               compatible = "st,stm32h7-timer-trigger";
-                               reg = <16>;
+                       cec: cec@40016000 {
+                               compatible = "st,stm32-cec";
+                               reg = <0x40016000 0x400>;
+                               interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CEC_K>, <&rcc CEC>;
+                               clock-names = "cec", "hdmi-cec";
+                               access-controllers = <&etzpc 38>;
                                status = "disabled";
                        };
-               };
 
-               spi5: spi@44009000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x44009000 0x400>;
-                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI5_K>;
-                       resets = <&rcc SPI5_R>;
-                       dmas = <&dmamux1 85 0x400 0x05>,
-                              <&dmamux1 86 0x400 0x05>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
+                       dac: dac@40017000 {
+                               compatible = "st,stm32h7-dac-core";
+                               reg = <0x40017000 0x400>;
+                               clocks = <&rcc DAC12>;
+                               clock-names = "pclk";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&etzpc 39>;
+                               status = "disabled";
 
-               sai1: sai@4400a000 {
-                       compatible = "st,stm32h7-sai";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4400a000 0x400>;
-                       reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
-                       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&rcc SAI1_R>;
-                       status = "disabled";
+                               dac1: dac@1 {
+                                       compatible = "st,stm32-dac";
+                                       #io-channel-cells = <1>;
+                                       reg = <1>;
+                                       status = "disabled";
+                               };
 
-                       sai1a: audio-controller@4400a004 {
-                               #sound-dai-cells = <0>;
+                               dac2: dac@2 {
+                                       compatible = "st,stm32-dac";
+                                       #io-channel-cells = <1>;
+                                       reg = <2>;
+                                       status = "disabled";
+                               };
+                       };
 
-                               compatible = "st,stm32-sai-sub-a";
-                               reg = <0x4 0x20>;
-                               clocks = <&rcc SAI1_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 87 0x400 0x01>;
+                       uart7: serial@40018000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x40018000 0x400>;
+                               interrupts-extended = <&exti 32 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc UART7_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 79 0x400 0x15>,
+                                      <&dmamux1 80 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 40>;
                                status = "disabled";
                        };
 
-                       sai1b: audio-controller@4400a024 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-b";
-                               reg = <0x24 0x20>;
-                               clocks = <&rcc SAI1_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 88 0x400 0x01>;
+                       uart8: serial@40019000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x40019000 0x400>;
+                               interrupts-extended = <&exti 33 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc UART8_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 81 0x400 0x15>,
+                                      <&dmamux1 82 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 41>;
                                status = "disabled";
                        };
-               };
 
-               sai2: sai@4400b000 {
-                       compatible = "st,stm32h7-sai";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4400b000 0x400>;
-                       reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
-                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&rcc SAI2_R>;
-                       status = "disabled";
+                       timers1: timer@44000000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x44000000 0x400>;
+                               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "brk", "up", "trg-com", "cc";
+                               clocks = <&rcc TIM1_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 11 0x400 0x1>,
+                                      <&dmamux1 12 0x400 0x1>,
+                                      <&dmamux1 13 0x400 0x1>,
+                                      <&dmamux1 14 0x400 0x1>,
+                                      <&dmamux1 15 0x400 0x1>,
+                                      <&dmamux1 16 0x400 0x1>,
+                                      <&dmamux1 17 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4",
+                                           "up", "trig", "com";
+                               access-controllers = <&etzpc 48>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       sai2a: audio-controller@4400b004 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-a";
-                               reg = <0x4 0x20>;
-                               clocks = <&rcc SAI2_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 89 0x400 0x01>;
-                               status = "disabled";
-                       };
+                               timer@0 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <0>;
+                                       status = "disabled";
+                               };
 
-                       sai2b: audio-controller@4400b024 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-b";
-                               reg = <0x24 0x20>;
-                               clocks = <&rcc SAI2_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 90 0x400 0x01>;
-                               status = "disabled";
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
                        };
-               };
 
-               sai3: sai@4400c000 {
-                       compatible = "st,stm32h7-sai";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x4400c000 0x400>;
-                       reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
-                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&rcc SAI3_R>;
-                       status = "disabled";
+                       timers8: timer@44001000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x44001000 0x400>;
+                               interrupts = <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>;
+                               interrupt-names = "brk", "up", "trg-com", "cc";
+                               clocks = <&rcc TIM8_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 47 0x400 0x1>,
+                                      <&dmamux1 48 0x400 0x1>,
+                                      <&dmamux1 49 0x400 0x1>,
+                                      <&dmamux1 50 0x400 0x1>,
+                                      <&dmamux1 51 0x400 0x1>,
+                                      <&dmamux1 52 0x400 0x1>,
+                                      <&dmamux1 53 0x400 0x1>;
+                               dma-names = "ch1", "ch2", "ch3", "ch4",
+                                           "up", "trig", "com";
+                               access-controllers = <&etzpc 49>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       sai3a: audio-controller@4400c004 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-a";
-                               reg = <0x04 0x20>;
-                               clocks = <&rcc SAI3_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 113 0x400 0x01>;
+                               timer@7 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <7>;
+                                       status = "disabled";
+                               };
+
+                               counter {
+                                       compatible = "st,stm32-timer-counter";
+                                       status = "disabled";
+                               };
+                       };
+
+                       usart6: serial@44003000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x44003000 0x400>;
+                               interrupts-extended = <&exti 29 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART6_K>;
+                               wakeup-source;
+                               dmas = <&dmamux1 71 0x400 0x15>,
+                               <&dmamux1 72 0x400 0x11>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 51>;
                                status = "disabled";
                        };
 
-                       sai3b: audio-controller@4400c024 {
+                       i2s1: audio-controller@44004000 {
+                               compatible = "st,stm32h7-i2s";
                                #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-b";
-                               reg = <0x24 0x20>;
-                               clocks = <&rcc SAI3_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 114 0x400 0x01>;
+                               reg = <0x44004000 0x400>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&dmamux1 37 0x400 0x01>,
+                               <&dmamux1 38 0x400 0x01>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 52>;
                                status = "disabled";
                        };
-               };
-
-               dfsdm: dfsdm@4400d000 {
-                       compatible = "st,stm32mp1-dfsdm";
-                       reg = <0x4400d000 0x800>;
-                       clocks = <&rcc DFSDM_K>;
-                       clock-names = "dfsdm";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
 
-                       dfsdm0: filter@0 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <0>;
-                               interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 101 0x400 0x01>;
-                               dma-names = "rx";
+                       spi1: spi@44004000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x44004000 0x400>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI1_K>;
+                               resets = <&rcc SPI1_R>;
+                               dmas = <&dmamux1 37 0x400 0x05>,
+                               <&dmamux1 38 0x400 0x05>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 52>;
                                status = "disabled";
                        };
 
-                       dfsdm1: filter@1 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <1>;
-                               interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 102 0x400 0x01>;
-                               dma-names = "rx";
+                       spi4: spi@44005000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x44005000 0x400>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI4_K>;
+                               resets = <&rcc SPI4_R>;
+                               dmas = <&dmamux1 83 0x400 0x05>,
+                               <&dmamux1 84 0x400 0x05>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 53>;
                                status = "disabled";
                        };
 
-                       dfsdm2: filter@2 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <2>;
-                               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 103 0x400 0x01>;
-                               dma-names = "rx";
-                               status = "disabled";
+                       timers15: timer@44006000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x44006000 0x400>;
+                               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM15_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 105 0x400 0x1>,
+                                      <&dmamux1 106 0x400 0x1>,
+                                      <&dmamux1 107 0x400 0x1>,
+                                      <&dmamux1 108 0x400 0x1>;
+                               dma-names = "ch1", "up", "trig", "com";
+                               access-controllers = <&etzpc 54>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@14 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <14>;
+                                       status = "disabled";
+                               };
                        };
 
-                       dfsdm3: filter@3 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <3>;
-                               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 104 0x400 0x01>;
-                               dma-names = "rx";
-                               status = "disabled";
+                       timers16: timer@44007000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x44007000 0x400>;
+                               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM16_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 109 0x400 0x1>,
+                               <&dmamux1 110 0x400 0x1>;
+                               dma-names = "ch1", "up";
+                               access-controllers = <&etzpc 55>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+                               timer@15 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <15>;
+                                       status = "disabled";
+                               };
                        };
 
-                       dfsdm4: filter@4 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <4>;
-                               interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 91 0x400 0x01>;
-                               dma-names = "rx";
-                               status = "disabled";
+                       timers17: timer@44008000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-timers";
+                               reg = <0x44008000 0x400>;
+                               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "global";
+                               clocks = <&rcc TIM17_K>;
+                               clock-names = "int";
+                               dmas = <&dmamux1 111 0x400 0x1>,
+                               <&dmamux1 112 0x400 0x1>;
+                               dma-names = "ch1", "up";
+                               access-controllers = <&etzpc 56>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
+
+                               timer@16 {
+                                       compatible = "st,stm32h7-timer-trigger";
+                                       reg = <16>;
+                                       status = "disabled";
+                               };
                        };
 
-                       dfsdm5: filter@5 {
-                               compatible = "st,stm32-dfsdm-adc";
-                               #io-channel-cells = <1>;
-                               reg = <5>;
-                               interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&dmamux1 92 0x400 0x01>;
-                               dma-names = "rx";
+                       spi5: spi@44009000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x44009000 0x400>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI5_K>;
+                               resets = <&rcc SPI5_R>;
+                               dmas = <&dmamux1 85 0x400 0x05>,
+                               <&dmamux1 86 0x400 0x05>;
+                               dma-names = "rx", "tx";
+                               access-controllers = <&etzpc 57>;
                                status = "disabled";
                        };
-               };
 
-               dma1: dma-controller@48000000 {
-                       compatible = "st,stm32-dma";
-                       reg = <0x48000000 0x400>;
-                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc DMA1>;
-                       resets = <&rcc DMA1_R>;
-                       #dma-cells = <4>;
-                       st,mem2mem;
-                       dma-requests = <8>;
-               };
+                       sai1: sai@4400a000 {
+                               compatible = "st,stm32h7-sai";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x4400a000 0x400>;
+                               reg = <0x4400a000 0x4>, <0x4400a3f0 0x10>;
+                               interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+                               resets = <&rcc SAI1_R>;
+                               access-controllers = <&etzpc 58>;
+                               status = "disabled";
+
+                               sai1a: audio-controller@4400a004 {
+                                       #sound-dai-cells = <0>;
+
+                                       compatible = "st,stm32-sai-sub-a";
+                                       reg = <0x4 0x20>;
+                                       clocks = <&rcc SAI1_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 87 0x400 0x01>;
+                                       status = "disabled";
+                               };
 
-               dma2: dma-controller@48001000 {
-                       compatible = "st,stm32-dma";
-                       reg = <0x48001000 0x400>;
-                       interrupts = <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 68 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc DMA2>;
-                       resets = <&rcc DMA2_R>;
-                       #dma-cells = <4>;
-                       st,mem2mem;
-                       dma-requests = <8>;
-               };
+                               sai1b: audio-controller@4400a024 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-b";
+                                       reg = <0x24 0x20>;
+                                       clocks = <&rcc SAI1_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 88 0x400 0x01>;
+                                       status = "disabled";
+                               };
+                       };
 
-               dmamux1: dma-router@48002000 {
-                       compatible = "st,stm32h7-dmamux";
-                       reg = <0x48002000 0x40>;
-                       #dma-cells = <3>;
-                       dma-requests = <128>;
-                       dma-masters = <&dma1 &dma2>;
-                       dma-channels = <16>;
-                       clocks = <&rcc DMAMUX>;
-                       resets = <&rcc DMAMUX_R>;
-               };
+                       sai2: sai@4400b000 {
+                               compatible = "st,stm32h7-sai";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x4400b000 0x400>;
+                               reg = <0x4400b000 0x4>, <0x4400b3f0 0x10>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                               resets = <&rcc SAI2_R>;
+                               access-controllers = <&etzpc 59>;
+                               status = "disabled";
+
+                               sai2a: audio-controller@4400b004 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-a";
+                                       reg = <0x4 0x20>;
+                                       clocks = <&rcc SAI2_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 89 0x400 0x01>;
+                                       status = "disabled";
+                               };
 
-               adc: adc@48003000 {
-                       compatible = "st,stm32mp1-adc-core";
-                       reg = <0x48003000 0x400>;
-                       interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc ADC12>, <&rcc ADC12_K>;
-                       clock-names = "bus", "adc";
-                       interrupt-controller;
-                       st,syscfg = <&syscfg>;
-                       #interrupt-cells = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
+                               sai2b: audio-controller@4400b024 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-b";
+                                       reg = <0x24 0x20>;
+                                       clocks = <&rcc SAI2_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 90 0x400 0x01>;
+                                       status = "disabled";
+                               };
+                       };
 
-                       adc1: adc@0 {
-                               compatible = "st,stm32mp1-adc";
-                               #io-channel-cells = <1>;
+                       sai3: sai@4400c000 {
+                               compatible = "st,stm32h7-sai";
                                #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <0x0>;
-                               interrupt-parent = <&adc>;
-                               interrupts = <0>;
-                               dmas = <&dmamux1 9 0x400 0x01>;
-                               dma-names = "rx";
-                               status = "disabled";
+                               #size-cells = <1>;
+                               ranges = <0 0x4400c000 0x400>;
+                               reg = <0x4400c000 0x4>, <0x4400c3f0 0x10>;
+                               interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                               resets = <&rcc SAI3_R>;
+                               access-controllers = <&etzpc 60>;
+                               status = "disabled";
+
+                               sai3a: audio-controller@4400c004 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-a";
+                                       reg = <0x04 0x20>;
+                                       clocks = <&rcc SAI3_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 113 0x400 0x01>;
+                                       status = "disabled";
+                               };
+
+                               sai3b: audio-controller@4400c024 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-b";
+                                       reg = <0x24 0x20>;
+                                       clocks = <&rcc SAI3_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 114 0x400 0x01>;
+                                       status = "disabled";
+                               };
                        };
 
-                       adc2: adc@100 {
-                               compatible = "st,stm32mp1-adc";
-                               #io-channel-cells = <1>;
+                       dfsdm: dfsdm@4400d000 {
+                               compatible = "st,stm32mp1-dfsdm";
+                               reg = <0x4400d000 0x800>;
+                               clocks = <&rcc DFSDM_K>;
+                               clock-names = "dfsdm";
                                #address-cells = <1>;
                                #size-cells = <0>;
-                               reg = <0x100>;
-                               interrupt-parent = <&adc>;
-                               interrupts = <1>;
-                               dmas = <&dmamux1 10 0x400 0x01>;
-                               dma-names = "rx";
-                               nvmem-cells = <&vrefint>;
-                               nvmem-cell-names = "vrefint";
-                               status = "disabled";
-                               channel@13 {
-                                       reg = <13>;
-                                       label = "vrefint";
+                               access-controllers = <&etzpc 61>;
+                               status = "disabled";
+
+                               dfsdm0: filter@0 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <0>;
+                                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 101 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
                                };
-                               channel@14 {
-                                       reg = <14>;
-                                       label = "vddcore";
+
+                               dfsdm1: filter@1 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <1>;
+                                       interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 102 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
                                };
-                       };
-               };
 
-               sdmmc3: mmc@48004000 {
-                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-                       arm,primecell-periphid = <0x00253180>;
-                       reg = <0x48004000 0x400>;
-                       interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
-                       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 = "st,stm32mp15-hsotg", "snps,dwc2";
-                       reg = <0x49000000 0x10000>;
-                       clocks = <&rcc USBO_K>, <&usbphyc>;
-                       clock-names = "otg", "utmi";
-                       resets = <&rcc USBO_R>;
-                       reset-names = "dwc2";
-                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
-                       g-rx-fifo-size = <512>;
-                       g-np-tx-fifo-size = <32>;
-                       g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
-                       dr_mode = "otg";
-                       otg-rev = <0x200>;
-                       usb33d-supply = <&usb33>;
-                       status = "disabled";
-               };
-
-               ipcc: mailbox@4c001000 {
-                       compatible = "st,stm32mp1-ipcc";
-                       #mbox-cells = <1>;
-                       reg = <0x4c001000 0x400>;
-                       st,proc-id = <0>;
-                       interrupts-extended =
-                               <&exti 61 1>,
-                               <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "rx", "tx";
-                       clocks = <&rcc IPCC>;
-                       wakeup-source;
-                       status = "disabled";
-               };
-
-               dcmi: dcmi@4c006000 {
-                       compatible = "st,stm32-dcmi";
-                       reg = <0x4c006000 0x400>;
-                       interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&rcc CAMITF_R>;
-                       clocks = <&rcc DCMI>;
-                       clock-names = "mclk";
-                       dmas = <&dmamux1 75 0x400 0x01>;
-                       dma-names = "tx";
-                       status = "disabled";
-               };
+                               dfsdm2: filter@2 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <2>;
+                                       interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 103 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+                               };
 
-               rcc: rcc@50000000 {
-                       compatible = "st,stm32mp1-rcc", "syscon";
-                       reg = <0x50000000 0x1000>;
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-               };
+                               dfsdm3: filter@3 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <3>;
+                                       interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 104 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+                               };
 
-               pwr_regulators: pwr@50001000 {
-                       compatible = "st,stm32mp1,pwr-reg";
-                       reg = <0x50001000 0x10>;
+                               dfsdm4: filter@4 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <4>;
+                                       interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 91 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+                               };
 
-                       reg11: reg11 {
-                               regulator-name = "reg11";
-                               regulator-min-microvolt = <1100000>;
-                               regulator-max-microvolt = <1100000>;
+                               dfsdm5: filter@5 {
+                                       compatible = "st,stm32-dfsdm-adc";
+                                       #io-channel-cells = <1>;
+                                       reg = <5>;
+                                       interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&dmamux1 92 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+                               };
                        };
 
-                       reg18: reg18 {
-                               regulator-name = "reg18";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                       };
+                       dma1: dma-controller@48000000 {
+                               compatible = "st,stm32-dma";
+                               reg = <0x48000000 0x400>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc DMA1>;
+                               resets = <&rcc DMA1_R>;
+                               #dma-cells = <4>;
+                               st,mem2mem;
+                               dma-requests = <8>;
+                               access-controllers = <&etzpc 88>;
+                       };
+
+                       dma2: dma-controller@48001000 {
+                               compatible = "st,stm32-dma";
+                               reg = <0x48001000 0x400>;
+                               interrupts = <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 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc DMA2>;
+                               resets = <&rcc DMA2_R>;
+                               #dma-cells = <4>;
+                               st,mem2mem;
+                               dma-requests = <8>;
+                               access-controllers = <&etzpc 89>;
+                       };
+
+                       dmamux1: dma-router@48002000 {
+                               compatible = "st,stm32h7-dmamux";
+                               reg = <0x48002000 0x40>;
+                               #dma-cells = <3>;
+                               dma-requests = <128>;
+                               dma-masters = <&dma1 &dma2>;
+                               dma-channels = <16>;
+                               clocks = <&rcc DMAMUX>;
+                               resets = <&rcc DMAMUX_R>;
+                               access-controllers = <&etzpc 90>;
+                       };
+
+                       adc: adc@48003000 {
+                               compatible = "st,stm32mp1-adc-core";
+                               reg = <0x48003000 0x400>;
+                               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc ADC12>, <&rcc ADC12_K>;
+                               clock-names = "bus", "adc";
+                               interrupt-controller;
+                               st,syscfg = <&syscfg>;
+                               #interrupt-cells = <1>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&etzpc 72>;
+                               status = "disabled";
+
+                               adc1: adc@0 {
+                                       compatible = "st,stm32mp1-adc";
+                                       #io-channel-cells = <1>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0x0>;
+                                       interrupt-parent = <&adc>;
+                                       interrupts = <0>;
+                                       dmas = <&dmamux1 9 0x400 0x01>;
+                                       dma-names = "rx";
+                                       status = "disabled";
+                               };
 
-                       usb33: usb33 {
-                               regulator-name = "usb33";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
+                               adc2: adc@100 {
+                                       compatible = "st,stm32mp1-adc";
+                                       #io-channel-cells = <1>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0x100>;
+                                       interrupt-parent = <&adc>;
+                                       interrupts = <1>;
+                                       dmas = <&dmamux1 10 0x400 0x01>;
+                                       dma-names = "rx";
+                                       nvmem-cells = <&vrefint>;
+                                       nvmem-cell-names = "vrefint";
+                                       status = "disabled";
+                                       channel@13 {
+                                               reg = <13>;
+                                               label = "vrefint";
+                                       };
+                                       channel@14 {
+                                               reg = <14>;
+                                               label = "vddcore";
+                                       };
+                               };
                        };
-               };
 
-               pwr_mcu: pwr_mcu@50001014 {
-                       compatible = "st,stm32mp151-pwr-mcu", "syscon";
-                       reg = <0x50001014 0x4>;
-               };
+                       sdmmc3: mmc@48004000 {
+                               compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+                               arm,primecell-periphid = <0x00253180>;
+                               reg = <0x48004000 0x400>;
+                               interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SDMMC3_K>;
+                               clock-names = "apb_pclk";
+                               resets = <&rcc SDMMC3_R>;
+                               cap-sd-highspeed;
+                               cap-mmc-highspeed;
+                               max-frequency = <120000000>;
+                               access-controllers = <&etzpc 86>;
+                               status = "disabled";
+                       };
+
+                       usbotg_hs: usb-otg@49000000 {
+                               compatible = "st,stm32mp15-hsotg", "snps,dwc2";
+                               reg = <0x49000000 0x10000>;
+                               clocks = <&rcc USBO_K>, <&usbphyc>;
+                               clock-names = "otg", "utmi";
+                               resets = <&rcc USBO_R>;
+                               reset-names = "dwc2";
+                               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+                               g-rx-fifo-size = <512>;
+                               g-np-tx-fifo-size = <32>;
+                               g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
+                               dr_mode = "otg";
+                               otg-rev = <0x200>;
+                               usb33d-supply = <&usb33>;
+                               access-controllers = <&etzpc 85>;
+                               status = "disabled";
+                       };
+
+                       dcmi: dcmi@4c006000 {
+                               compatible = "st,stm32-dcmi";
+                               reg = <0x4c006000 0x400>;
+                               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+                               resets = <&rcc CAMITF_R>;
+                               clocks = <&rcc DCMI>;
+                               clock-names = "mclk";
+                               dmas = <&dmamux1 75 0x400 0x01>;
+                               dma-names = "tx";
+                               access-controllers = <&etzpc 70>;
+                               status = "disabled";
+                       };
+
+                       lptimer2: timer@50021000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50021000 0x400>;
+                               interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM2_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 64>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-               exti: interrupt-controller@5000d000 {
-                       compatible = "st,stm32mp1-exti", "syscon";
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-                       reg = <0x5000d000 0x400>;
-               };
+                               trigger@1 {
+                                       compatible = "st,stm32-lptimer-trigger";
+                                       reg = <1>;
+                                       status = "disabled";
+                               };
 
-               syscfg: syscon@50020000 {
-                       compatible = "st,stm32mp157-syscfg", "syscon";
-                       reg = <0x50020000 0x400>;
-                       clocks = <&rcc SYSCFG>;
-               };
+                               counter {
+                                       compatible = "st,stm32-lptimer-counter";
+                                       status = "disabled";
+                               };
+                       };
 
-               lptimer2: timer@50021000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50021000 0x400>;
-                       interrupts-extended = <&exti 48 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM2_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
+                       lptimer3: timer@50022000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50022000 0x400>;
+                               interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM3_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 65>;
+                               status = "disabled";
+
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
-                               status = "disabled";
+                               trigger@2 {
+                                       compatible = "st,stm32-lptimer-trigger";
+                                       reg = <2>;
+                                       status = "disabled";
+                               };
                        };
 
-                       trigger@1 {
-                               compatible = "st,stm32-lptimer-trigger";
-                               reg = <1>;
+                       lptimer4: timer@50023000 {
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50023000 0x400>;
+                               interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM4_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 66>;
                                status = "disabled";
-                       };
 
-                       counter {
-                               compatible = "st,stm32-lptimer-counter";
-                               status = "disabled";
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
                        };
-               };
 
-               lptimer3: timer@50022000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50022000 0x400>;
-                       interrupts-extended = <&exti 50 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM3_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
-
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
+                       lptimer5: timer@50024000 {
+                               compatible = "st,stm32-lptimer";
+                               reg = <0x50024000 0x400>;
+                               interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc LPTIM5_K>;
+                               clock-names = "mux";
+                               wakeup-source;
+                               access-controllers = <&etzpc 67>;
                                status = "disabled";
-                       };
 
-                       trigger@2 {
-                               compatible = "st,stm32-lptimer-trigger";
-                               reg = <2>;
-                               status = "disabled";
+                               pwm {
+                                       compatible = "st,stm32-pwm-lp";
+                                       #pwm-cells = <3>;
+                                       status = "disabled";
+                               };
                        };
-               };
-
-               lptimer4: timer@50023000 {
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50023000 0x400>;
-                       interrupts-extended = <&exti 52 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM4_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
 
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
+                       vrefbuf: vrefbuf@50025000 {
+                               compatible = "st,stm32-vrefbuf";
+                               reg = <0x50025000 0x8>;
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <2500000>;
+                               clocks = <&rcc VREF>;
+                               access-controllers = <&etzpc 69>;
                                status = "disabled";
                        };
-               };
 
-               lptimer5: timer@50024000 {
-                       compatible = "st,stm32-lptimer";
-                       reg = <0x50024000 0x400>;
-                       interrupts-extended = <&exti 53 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LPTIM5_K>;
-                       clock-names = "mux";
-                       wakeup-source;
-                       status = "disabled";
+                       sai4: sai@50027000 {
+                               compatible = "st,stm32h7-sai";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x50027000 0x400>;
+                               reg = <0x50027000 0x4>, <0x500273f0 0x10>;
+                               interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                               resets = <&rcc SAI4_R>;
+                               access-controllers = <&etzpc 68>;
+                               status = "disabled";
+
+                               sai4a: audio-controller@50027004 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-a";
+                                       reg = <0x04 0x20>;
+                                       clocks = <&rcc SAI4_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 99 0x400 0x01>;
+                                       status = "disabled";
+                               };
 
-                       pwm {
-                               compatible = "st,stm32-pwm-lp";
-                               #pwm-cells = <3>;
-                               status = "disabled";
+                               sai4b: audio-controller@50027024 {
+                                       #sound-dai-cells = <0>;
+                                       compatible = "st,stm32-sai-sub-b";
+                                       reg = <0x24 0x20>;
+                                       clocks = <&rcc SAI4_K>;
+                                       clock-names = "sai_ck";
+                                       dmas = <&dmamux1 100 0x400 0x01>;
+                                       status = "disabled";
+                               };
                        };
-               };
 
-               vrefbuf: vrefbuf@50025000 {
-                       compatible = "st,stm32-vrefbuf";
-                       reg = <0x50025000 0x8>;
-                       regulator-min-microvolt = <1500000>;
-                       regulator-max-microvolt = <2500000>;
-                       clocks = <&rcc VREF>;
-                       status = "disabled";
-               };
-
-               sai4: sai@50027000 {
-                       compatible = "st,stm32h7-sai";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges = <0 0x50027000 0x400>;
-                       reg = <0x50027000 0x4>, <0x500273f0 0x10>;
-                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&rcc SAI4_R>;
-                       status = "disabled";
+                       hash1: hash@54002000 {
+                               compatible = "st,stm32f756-hash";
+                               reg = <0x54002000 0x400>;
+                               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc HASH1>;
+                               resets = <&rcc HASH1_R>;
+                               dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>;
+                               dma-names = "in";
+                               dma-maxburst = <2>;
+                               access-controllers = <&etzpc 8>;
+                               status = "disabled";
+                       };
+
+                       rng1: rng@54003000 {
+                               compatible = "st,stm32-rng";
+                               reg = <0x54003000 0x400>;
+                               clocks = <&rcc RNG1_K>;
+                               resets = <&rcc RNG1_R>;
+                               access-controllers = <&etzpc 7>;
+                               status = "disabled";
+                       };
+
+                       fmc: memory-controller@58002000 {
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               compatible = "st,stm32mp1-fmc2-ebi";
+                               reg = <0x58002000 0x1000>;
+                               clocks = <&rcc FMC_K>;
+                               resets = <&rcc FMC_R>;
+                               access-controllers = <&etzpc 91>;
+                               status = "disabled";
+
+                               ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
+                                        <1 0 0x64000000 0x04000000>, /* EBI CS 2 */
+                                        <2 0 0x68000000 0x04000000>, /* EBI CS 3 */
+                                        <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */
+                                        <4 0 0x80000000 0x10000000>; /* NAND */
+
+                               nand-controller@4,0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "st,stm32mp1-fmc2-nfc";
+                                       reg = <4 0x00000000 0x1000>,
+                                             <4 0x08010000 0x1000>,
+                                             <4 0x08020000 0x1000>,
+                                             <4 0x01000000 0x1000>,
+                                             <4 0x09010000 0x1000>,
+                                             <4 0x09020000 0x1000>;
+                                       interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>,
+                                              <&mdma1 20 0x2 0x12000a08 0x0 0x0>,
+                                              <&mdma1 21 0x2 0x12000a0a 0x0 0x0>;
+                                       dma-names = "tx", "rx", "ecc";
+                                       status = "disabled";
+                               };
+                       };
 
-                       sai4a: audio-controller@50027004 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-a";
-                               reg = <0x04 0x20>;
-                               clocks = <&rcc SAI4_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 99 0x400 0x01>;
-                               status = "disabled";
+                       qspi: spi@58003000 {
+                               compatible = "st,stm32f469-qspi";
+                               reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+                               reg-names = "qspi", "qspi_mm";
+                               interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0>,
+                                      <&mdma1 22 0x2 0x10100008 0x0 0x0>;
+                               dma-names = "tx", "rx";
+                               clocks = <&rcc QSPI_K>;
+                               resets = <&rcc QSPI_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&etzpc 92>;
+                               status = "disabled";
+                       };
+
+                       ethernet0: ethernet@5800a000 {
+                               compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
+                               reg = <0x5800a000 0x2000>;
+                               reg-names = "stmmaceth";
+                               interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "macirq";
+                               clock-names = "stmmaceth",
+                                             "mac-clk-tx",
+                                             "mac-clk-rx",
+                                             "eth-ck",
+                                             "ptp_ref",
+                                             "ethstp";
+                               clocks = <&rcc ETHMAC>,
+                                        <&rcc ETHTX>,
+                                        <&rcc ETHRX>,
+                                        <&rcc ETHCK_K>,
+                                        <&rcc ETHPTP_K>,
+                                        <&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;
+                               access-controllers = <&etzpc 94>;
+                               status = "disabled";
+
+                               stmmac_axi_config_0: stmmac-axi-config {
+                                       snps,wr_osr_lmt = <0x7>;
+                                       snps,rd_osr_lmt = <0x7>;
+                                       snps,blen = <0 0 0 0 16 8 4>;
+                               };
                        };
 
-                       sai4b: audio-controller@50027024 {
-                               #sound-dai-cells = <0>;
-                               compatible = "st,stm32-sai-sub-b";
-                               reg = <0x24 0x20>;
-                               clocks = <&rcc SAI4_K>;
-                               clock-names = "sai_ck";
-                               dmas = <&dmamux1 100 0x400 0x01>;
+                       usart1: serial@5c000000 {
+                               compatible = "st,stm32h7-uart";
+                               reg = <0x5c000000 0x400>;
+                               interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc USART1_K>;
+                               wakeup-source;
+                               access-controllers = <&etzpc 3>;
                                status = "disabled";
                        };
-               };
-
-               dts: thermal@50028000 {
-                       compatible = "st,stm32-thermal";
-                       reg = <0x50028000 0x100>;
-                       interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc TMPSENS>;
-                       clock-names = "pclk";
-                       #thermal-sensor-cells = <0>;
-                       status = "disabled";
-               };
 
-               hash1: hash@54002000 {
-                       compatible = "st,stm32f756-hash";
-                       reg = <0x54002000 0x400>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc HASH1>;
-                       resets = <&rcc HASH1_R>;
-                       dmas = <&mdma1 31 0x2 0x1000A02 0x0 0x0>;
-                       dma-names = "in";
-                       dma-maxburst = <2>;
-                       status = "disabled";
-               };
-
-               rng1: rng@54003000 {
-                       compatible = "st,stm32-rng";
-                       reg = <0x54003000 0x400>;
-                       clocks = <&rcc RNG1_K>;
-                       resets = <&rcc RNG1_R>;
-                       status = "disabled";
-               };
-
-               mdma1: dma-controller@58000000 {
-                       compatible = "st,stm32h7-mdma";
-                       reg = <0x58000000 0x1000>;
-                       interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc MDMA>;
-                       resets = <&rcc MDMA_R>;
-                       #dma-cells = <5>;
-                       dma-channels = <32>;
-                       dma-requests = <48>;
-               };
-
-               fmc: memory-controller@58002000 {
-                       #address-cells = <2>;
-                       #size-cells = <1>;
-                       compatible = "st,stm32mp1-fmc2-ebi";
-                       reg = <0x58002000 0x1000>;
-                       clocks = <&rcc FMC_K>;
-                       resets = <&rcc FMC_R>;
-                       status = "disabled";
-
-                       ranges = <0 0 0x60000000 0x04000000>, /* EBI CS 1 */
-                                <1 0 0x64000000 0x04000000>, /* EBI CS 2 */
-                                <2 0 0x68000000 0x04000000>, /* EBI CS 3 */
-                                <3 0 0x6c000000 0x04000000>, /* EBI CS 4 */
-                                <4 0 0x80000000 0x10000000>; /* NAND */
-
-                       nand-controller@4,0 {
+                       spi6: spi@5c001000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32h7-spi";
+                               reg = <0x5c001000 0x400>;
+                               interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc SPI6_K>;
+                               resets = <&rcc SPI6_R>;
+                               dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
+                                      <&mdma1 35 0x0 0x40002 0x0 0x0>;
+                               access-controllers = <&etzpc 4>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@5c002000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x5c002000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C4_K>;
+                               resets = <&rcc I2C4_R>;
                                #address-cells = <1>;
                                #size-cells = <0>;
-                               compatible = "st,stm32mp1-fmc2-nfc";
-                               reg = <4 0x00000000 0x1000>,
-                                     <4 0x08010000 0x1000>,
-                                     <4 0x08020000 0x1000>,
-                                     <4 0x01000000 0x1000>,
-                                     <4 0x09010000 0x1000>,
-                                     <4 0x09020000 0x1000>;
-                               interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
-                               dmas = <&mdma1 20 0x2 0x12000a02 0x0 0x0>,
-                                      <&mdma1 20 0x2 0x12000a08 0x0 0x0>,
-                                      <&mdma1 21 0x2 0x12000a0a 0x0 0x0>;
-                               dma-names = "tx", "rx", "ecc";
+                               st,syscfg-fmp = <&syscfg 0x4 0x8>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 5>;
                                status = "disabled";
                        };
-               };
-
-               qspi: spi@58003000 {
-                       compatible = "st,stm32f469-qspi";
-                       reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
-                       reg-names = "qspi", "qspi_mm";
-                       interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&mdma1 22 0x2 0x10100002 0x0 0x0>,
-                              <&mdma1 22 0x2 0x10100008 0x0 0x0>;
-                       dma-names = "tx", "rx";
-                       clocks = <&rcc QSPI_K>;
-                       resets = <&rcc QSPI_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               sdmmc1: mmc@58005000 {
-                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-                       arm,primecell-periphid = <0x00253180>;
-                       reg = <0x58005000 0x1000>;
-                       interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SDMMC1_K>;
-                       clock-names = "apb_pclk";
-                       resets = <&rcc SDMMC1_R>;
-                       cap-sd-highspeed;
-                       cap-mmc-highspeed;
-                       max-frequency = <120000000>;
-                       status = "disabled";
-               };
-
-               sdmmc2: mmc@58007000 {
-                       compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-                       arm,primecell-periphid = <0x00253180>;
-                       reg = <0x58007000 0x1000>;
-                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-                       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 {
-                       compatible = "st,stm32f7-crc";
-                       reg = <0x58009000 0x400>;
-                       clocks = <&rcc CRC1>;
-                       status = "disabled";
-               };
-
-               ethernet0: ethernet@5800a000 {
-                       compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
-                       reg = <0x5800a000 0x2000>;
-                       reg-names = "stmmaceth";
-                       interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "macirq";
-                       clock-names = "stmmaceth",
-                                     "mac-clk-tx",
-                                     "mac-clk-rx",
-                                     "eth-ck",
-                                     "ptp_ref",
-                                     "ethstp";
-                       clocks = <&rcc ETHMAC>,
-                                <&rcc ETHTX>,
-                                <&rcc ETHRX>,
-                                <&rcc ETHCK_K>,
-                                <&rcc ETHPTP_K>,
-                                <&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";
-
-                       stmmac_axi_config_0: stmmac-axi-config {
-                               snps,wr_osr_lmt = <0x7>;
-                               snps,rd_osr_lmt = <0x7>;
-                               snps,blen = <0 0 0 0 16 8 4>;
-                       };
-               };
-
-               usbh_ohci: usb@5800c000 {
-                       compatible = "generic-ohci";
-                       reg = <0x5800c000 0x1000>;
-                       clocks = <&usbphyc>, <&rcc USBH>;
-                       resets = <&rcc USBH_R>;
-                       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-                       phys = <&usbphyc_port0>;
-                       phy-names = "usb";
-                       status = "disabled";
-               };
-
-               usbh_ehci: usb@5800d000 {
-                       compatible = "generic-ehci";
-                       reg = <0x5800d000 0x1000>;
-                       clocks = <&usbphyc>, <&rcc USBH>;
-                       resets = <&rcc USBH_R>;
-                       interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-                       companion = <&usbh_ohci>;
-                       phys = <&usbphyc_port0>;
-                       phy-names = "usb";
-                       status = "disabled";
-               };
-
-               ltdc: display-controller@5a001000 {
-                       compatible = "st,stm32-ltdc";
-                       reg = <0x5a001000 0x400>;
-                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc LTDC_PX>;
-                       clock-names = "lcd";
-                       resets = <&rcc LTDC_R>;
-                       status = "disabled";
-               };
 
-               iwdg2: watchdog@5a002000 {
-                       compatible = "st,stm32mp1-iwdg";
-                       reg = <0x5a002000 0x400>;
-                       clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
-                       clock-names = "pclk", "lsi";
-                       status = "disabled";
-               };
-
-               usbphyc: usbphyc@5a006000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       #clock-cells = <0>;
-                       compatible = "st,stm32mp1-usbphyc";
-                       reg = <0x5a006000 0x1000>;
-                       clocks = <&rcc USBPHY_K>;
-                       resets = <&rcc USBPHY_R>;
-                       vdda1v1-supply = <&reg11>;
-                       vdda1v8-supply = <&reg18>;
-                       status = "disabled";
-
-                       usbphyc_port0: usb-phy@0 {
-                               #phy-cells = <0>;
-                               reg = <0>;
-                       };
-
-                       usbphyc_port1: usb-phy@1 {
-                               #phy-cells = <1>;
-                               reg = <1>;
-                       };
-               };
-
-               usart1: serial@5c000000 {
-                       compatible = "st,stm32h7-uart";
-                       reg = <0x5c000000 0x400>;
-                       interrupts-extended = <&exti 26 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc USART1_K>;
-                       wakeup-source;
-                       status = "disabled";
-               };
-
-               spi6: spi@5c001000 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       compatible = "st,stm32h7-spi";
-                       reg = <0x5c001000 0x400>;
-                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc SPI6_K>;
-                       resets = <&rcc SPI6_R>;
-                       dmas = <&mdma1 34 0x0 0x40008 0x0 0x0>,
-                              <&mdma1 35 0x0 0x40002 0x0 0x0>;
-                       dma-names = "rx", "tx";
-                       status = "disabled";
-               };
-
-               i2c4: i2c@5c002000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x5c002000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C4_K>;
-                       resets = <&rcc I2C4_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x8>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
-
-               rtc: rtc@5c004000 {
-                       compatible = "st,stm32mp1-rtc";
-                       reg = <0x5c004000 0x400>;
-                       clocks = <&rcc RTCAPB>, <&rcc RTC>;
-                       clock-names = "pclk", "rtc_ck";
-                       interrupts-extended = <&exti 19 IRQ_TYPE_LEVEL_HIGH>;
-                       status = "disabled";
-               };
-
-               bsec: efuse@5c005000 {
-                       compatible = "st,stm32mp15-bsec";
-                       reg = <0x5c005000 0x400>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       part_number_otp: part-number-otp@4 {
-                               reg = <0x4 0x1>;
-                       };
-                       vrefint: vrefin-cal@52 {
-                               reg = <0x52 0x2>;
-                       };
-                       ts_cal1: calib@5c {
-                               reg = <0x5c 0x2>;
-                       };
-                       ts_cal2: calib@5e {
-                               reg = <0x5e 0x2>;
+                       i2c6: i2c@5c009000 {
+                               compatible = "st,stm32mp15-i2c";
+                               reg = <0x5c009000 0x400>;
+                               interrupt-names = "event", "error";
+                               interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc I2C6_K>;
+                               resets = <&rcc I2C6_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               st,syscfg-fmp = <&syscfg 0x4 0x20>;
+                               wakeup-source;
+                               i2c-analog-filter;
+                               access-controllers = <&etzpc 12>;
+                               status = "disabled";
                        };
                };
 
-               i2c6: i2c@5c009000 {
-                       compatible = "st,stm32mp15-i2c";
-                       reg = <0x5c009000 0x400>;
-                       interrupt-names = "event", "error";
-                       interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc I2C6_K>;
-                       resets = <&rcc I2C6_R>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       st,syscfg-fmp = <&syscfg 0x4 0x20>;
-                       wakeup-source;
-                       i2c-analog-filter;
-                       status = "disabled";
-               };
-
                tamp: tamp@5c00a000 {
                        compatible = "st,stm32-tamp", "syscon", "simple-mfd";
                        reg = <0x5c00a000 0x400>;
index 486084e0b80b5df0fc3c581641918c90c23dbe2a..4640dafb1598c2701b6db1903530636a78e60369 100644 (file)
                             <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
                             <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
        };
+};
 
-       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";
-               };
+&etzpc {
+       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>;
+               access-controllers = <&etzpc 62>;
+               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";
-               };
+       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>;
+               access-controllers = <&etzpc 62>;
+               status = "disabled";
        };
 };
index 66ed5f9921ba14d96c5dcc2cc6f4c53cce3f54c9..9cf5ed111b52e167c678ddd5f429cac1b7162ce2 100644 (file)
@@ -10,6 +10,7 @@
 #include "stm32mp15-pinctrl.dtsi"
 #include "stm32mp15xxaa-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
 / {
                };
        };
 
+       led {
+               compatible = "gpio-leds";
+               led-blue {
+                       gpios = <&gpiod 9 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+                       function = LED_FUNCTION_HEARTBEAT;
+                       color = <LED_COLOR_ID_BLUE>;
+               };
+       };
+
        sd_switch: regulator-sd_switch {
                compatible = "regulator-gpio";
                regulator-name = "sd_switch";
index b06a55a2fa188dfb7f5212f887d6e80e01b20e9a..97465717f932fc223647af76e88a6182cf3c870f 100644 (file)
@@ -4,15 +4,14 @@
  * 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";
-               };
+&etzpc {
+       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>;
+               access-controllers = <&etzpc 9>;
+               status = "disabled";
        };
 };
index 790b29ab0fa2cdc0b73105a406de3eab23ade9c5..dafe485dfe197f2aa13c259cd54c3efeb209e0f3 100644 (file)
 
                pmmc: system-controller@2921c00 {
                        compatible = "ti,k2g-sci";
-                       /*
-                        * In case of rare platforms that does not use k2g as
-                        * system master, use /delete-property/
-                        */
-                       ti,system-reboot-controller;
                        mbox-names = "rx", "tx";
                        mboxes = <&msgmgr 5 2>,
                                <&msgmgr 0 0>;
index 989d5a6edeed9c7516b0848897a8764d1f6c9de9..0614ffdc1578f9a288683c59e4807e6adcab9466 100644 (file)
@@ -80,7 +80,7 @@
                 * because the can not be enabled simultaneously on a
                 * single SoC.
                 */
-               opp-50-300000000{
+               opp-50-300000000 {
                        /* OPP50 */
                        opp-hz = /bits/ 64 <300000000>;
                        opp-microvolt = <950000 931000 969000>;
@@ -88,7 +88,7 @@
                        opp-suspend;
                };
 
-               opp-100-275000000{
+               opp-100-275000000 {
                        /* OPP100-1 */
                        opp-hz = /bits/ 64 <275000000>;
                        opp-microvolt = <1100000 1078000 1122000>;
@@ -96,7 +96,7 @@
                        opp-suspend;
                };
 
-               opp-100-300000000{
+               opp-100-300000000 {
                        /* OPP100-2 */
                        opp-hz = /bits/ 64 <300000000>;
                        opp-microvolt = <1100000 1078000 1122000>;
                        opp-suspend;
                };
 
-               opp-100-500000000{
+               opp-100-500000000 {
                        /* OPP100-3 */
                        opp-hz = /bits/ 64 <500000000>;
                        opp-microvolt = <1100000 1078000 1122000>;
index 5fd1b380ece6280516c0e141f68a3a969b42d509..0a1df30f2818b2619d510773b95c773a97fe973e 100644 (file)
@@ -92,7 +92,7 @@
                        opp-supported-hw = <0xFF 0x08>;
                };
 
-               opp-800000000{
+               opp-800000000 {
                        /* OPP Turbo */
                        opp-hz = /bits/ 64 <800000000>;
                        opp-microvolt = <1260000 1234800 1285200>;
index 1045eb24aa0dbc2e81e8218371d669ce85a5235a..50a02c393ea27855f86c9d9a153877ea1c5dfc4f 100644 (file)
 };
 
 &scm_conf_clocks {
-       dpll_gmac_h14x2_ctrl_ck: dpll_gmac_h14x2_ctrl_ck@3fc {
-               #clock-cells = <0>;
-               compatible = "ti,divider-clock";
-               clocks = <&dpll_gmac_x2_ck>;
-               ti,max-div = <63>;
-               reg = <0x03fc>;
-               ti,bit-shift = <20>;
-               ti,latch-bit = <26>;
-               assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
-               assigned-clock-rates = <80000000>;
-       };
-
-       dpll_gmac_h14x2_ctrl_mux_ck: dpll_gmac_h14x2_ctrl_mux_ck@3fc {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
+       /* CTRL_CORE_SMA_SW_0 */
+       clock@3fc {
+               compatible = "ti,clksel";
                reg = <0x3fc>;
-               ti,bit-shift = <29>;
-               ti,latch-bit = <26>;
-               assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
-               assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
-       };
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_gmac_h14x2_ctrl_ck: clock@20 {
+                       reg = <20>;
+                       clock-output-names = "dpll_gmac_h14x2_ctrl_ck";
+                       compatible = "ti,divider-clock";
+                       clocks = <&dpll_gmac_x2_ck>;
+                       ti,max-div = <63>;
+                       ti,latch-bit = <26>;
+                       assigned-clocks = <&dpll_gmac_h14x2_ctrl_ck>;
+                       assigned-clock-rates = <80000000>;
+                       #clock-cells = <0>;
+               };
 
-       mcan_clk: mcan_clk@3fc {
-               #clock-cells = <0>;
-               compatible = "ti,gate-clock";
-               clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
-               ti,bit-shift = <27>;
-               reg = <0x3fc>;
+               mcan_clk: clock@27 {
+                       reg = <27>;
+                       clock-output-names = "mcan_clk";
+                       compatible = "ti,gate-clock";
+                       clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+                       #clock-cells = <0>;
+               };
+
+               dpll_gmac_h14x2_ctrl_mux_ck: clock@29 {
+                       reg = <29>;
+                       clock-output-names = "dpll_gmac_h14x2_ctrl_mux_ck";
+                       compatible = "ti,mux-clock";
+                       clocks = <&dpll_gmac_ck>, <&dpll_gmac_h14x2_ctrl_ck>;
+                       ti,latch-bit = <26>;
+                       assigned-clocks = <&dpll_gmac_h14x2_ctrl_mux_ck>;
+                       assigned-clock-parents = <&dpll_gmac_h14x2_ctrl_ck>;
+                       #clock-cells = <0>;
+               };
        };
 };
 
index 06466d36caa9f27b8782b47ab42c1bd8a11fda71..04f08b8c64d2783b7afb7d0980c6c3d380e23d3b 100644 (file)
                ti,invert-autoidle-bit;
        };
 
-       dpll_core_byp_mux: clock-dpll-core-byp-mux-23@12c {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_core_byp_mux";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
-               ti,bit-shift = <23>;
-               reg = <0x012c>;
+       /* CM_CLKSEL_DPLL_CORE */
+       clock@12c {
+               compatible = "ti,clksel";
+               reg = <0x12c>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_core_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_core_byp_mux";
+                       clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_core_ck: clock@120 {
                clock-div = <1>;
        };
 
-       dpll_dsp_byp_mux: clock-dpll-dsp-byp-mux-23@240 {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_dsp_byp_mux";
-               clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
-               ti,bit-shift = <23>;
-               reg = <0x0240>;
+       /* CM_CLKSEL_DPLL_DSP */
+       clock@240 {
+               compatible = "ti,clksel";
+               reg = <0x240>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_dsp_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_dsp_byp_mux";
+                       clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_dsp_ck: clock@234 {
                clock-div = <1>;
        };
 
-       dpll_iva_byp_mux: clock-dpll-iva-byp-mux-23@1ac {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_iva_byp_mux";
-               clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
-               ti,bit-shift = <23>;
-               reg = <0x01ac>;
+       /* CM_CLKSEL_DPLL_IVA */
+       clock@1ac {
+               compatible = "ti,clksel";
+               reg = <0x1ac>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_iva_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_iva_byp_mux";
+                       clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_iva_ck: clock@1a0 {
                clock-div = <1>;
        };
 
-       dpll_gpu_byp_mux: clock-dpll-gpu-byp-mux-23@2e4 {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_gpu_byp_mux";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
-               ti,bit-shift = <23>;
-               reg = <0x02e4>;
+       /* CM_CLKSEL_DPLL_GPU */
+       clock@2e4 {
+               compatible = "ti,clksel";
+               reg = <0x2e4>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_gpu_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_gpu_byp_mux";
+                       clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_gpu_ck: clock@2d8 {
                clock-div = <1>;
        };
 
-       dpll_ddr_byp_mux: clock-dpll-ddr-byp-mux-23@21c {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_ddr_byp_mux";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
-               ti,bit-shift = <23>;
-               reg = <0x021c>;
+       /* CM_CLKSEL_DPLL_DDR */
+       clock@21c {
+               compatible = "ti,clksel";
+               reg = <0x21c>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_ddr_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_ddr_byp_mux";
+                       clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_ddr_ck: clock@210 {
                ti,invert-autoidle-bit;
        };
 
-       dpll_gmac_byp_mux: clock-dpll-gmac-byp-mux-23@2b4 {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_gmac_byp_mux";
-               clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
-               ti,bit-shift = <23>;
-               reg = <0x02b4>;
+       /* CM_CLKSEL_DPLL_GMAC */
+       clock@2b4 {
+               compatible = "ti,clksel";
+               reg = <0x2b4>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_gmac_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_gmac_byp_mux";
+                       clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_gmac_ck: clock@2a8 {
                clock-div = <1>;
        };
 
-       dpll_eve_byp_mux: clock-dpll-eve-byp-mux-23@290 {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_eve_byp_mux";
-               clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
-               ti,bit-shift = <23>;
-               reg = <0x0290>;
+       /* CM_CLKSEL_DPLL_EVE */
+       clock@290 {
+               compatible = "ti,clksel";
+               reg = <0x290>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_eve_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_eve_byp_mux";
+                       clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_eve_ck: clock@284 {
                clock-div = <1>;
        };
 
-       l3_iclk_div: clock-l3-iclk-div-4@100 {
-               #clock-cells = <0>;
-               compatible = "ti,divider-clock";
-               clock-output-names = "l3_iclk_div";
-               ti,max-div = <2>;
-               ti,bit-shift = <4>;
-               reg = <0x0100>;
-               clocks = <&dpll_core_h12x2_ck>;
-               ti,index-power-of-two;
+       /* CM_CLKSEL_CORE */
+       clock@100 {
+               compatible = "ti,clksel";
+               reg = <0x100>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               l3_iclk_div: clock@4 {
+                       reg = <4>;
+                       compatible = "ti,divider-clock";
+                       clock-output-names = "l3_iclk_div";
+                       ti,max-div = <2>;
+                       clocks = <&dpll_core_h12x2_ck>;
+                       ti,index-power-of-two;
+                       #clock-cells = <0>;
+               };
        };
 
        l4_root_clk_div: clock-l4-root-clk-div {
                ti,index-starts-at-one;
        };
 
-       abe_dpll_sys_clk_mux: clock-abe-dpll-sys-clk-mux@118 {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "abe_dpll_sys_clk_mux";
-               clocks = <&sys_clkin1>, <&sys_clkin2>;
-               reg = <0x0118>;
+       /* CM_CLKSEL_ABE_PLL_SYS */
+       clock@118 {
+               compatible = "ti,clksel";
+               reg = <0x118>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               abe_dpll_sys_clk_mux: clock@0 {
+                       reg = <0>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "abe_dpll_sys_clk_mux";
+                       clocks = <&sys_clkin1>, <&sys_clkin2>;
+                       #clock-cells = <0>;
+               };
        };
 
        abe_dpll_bypass_clk_mux: clock-abe-dpll-bypass-clk-mux@114 {
                ti,index-power-of-two;
        };
 
-       dsp_gclk_div: clock-dsp-gclk-div@18c {
-               #clock-cells = <0>;
-               compatible = "ti,divider-clock";
-               clock-output-names = "dsp_gclk_div";
-               clocks = <&dpll_dsp_m2_ck>;
-               ti,max-div = <64>;
-               reg = <0x018c>;
-               ti,index-power-of-two;
+       /* CM_CLKSEL_DPLL_USB */
+       clock@18c {
+               compatible = "ti,clksel";
+               reg = <0x18c>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dsp_gclk_div: clock@0 {
+                       reg = <0>;
+                       compatible = "ti,divider-clock";
+                       clock-output-names = "dsp_gclk_div";
+                       clocks = <&dpll_dsp_m2_ck>;
+                       ti,max-div = <64>;
+                       ti,index-power-of-two;
+                       #clock-cells = <0>;
+               };
        };
 
        gpu_dclk: clock-gpu-dclk@1a0 {
                clock-div = <1>;
        };
 
-       dpll_per_byp_mux: clock-dpll-per-byp-mux-23@14c {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_per_byp_mux";
-               clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
-               ti,bit-shift = <23>;
-               reg = <0x014c>;
+       /* CM_CLKSEL_DPLL_PER */
+       clock@14c {
+               compatible = "ti,clksel";
+               reg = <0x14c>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_per_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_per_byp_mux";
+                       clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_per_ck: clock@140 {
                clock-div = <1>;
        };
 
-       dpll_usb_byp_mux: clock-dpll-usb-byp-mux-23@18c {
-               #clock-cells = <0>;
-               compatible = "ti,mux-clock";
-               clock-output-names = "dpll_usb_byp_mux";
-               clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
-               ti,bit-shift = <23>;
-               reg = <0x018c>;
+       /* CM_CLKSEL_DPLL_USB */
+       clock@18c {
+               compatible = "ti,clksel";
+               reg = <0x18c>;
+               #clock-cells = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dpll_usb_byp_mux: clock@23 {
+                       reg = <23>;
+                       compatible = "ti,mux-clock";
+                       clock-output-names = "dpll_usb_byp_mux";
+                       clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>;
+                       #clock-cells = <0>;
+               };
        };
 
        dpll_usb_ck: clock@180 {
index d334853412517378b460577067da2241cde0d319..07c5b963af78ab2347d2e8bb59b3c80937a8e396 100644 (file)
                ti,current-limit = <100>;
                ti,weak-battery-voltage = <3400>;
                ti,battery-regulation-voltage = <4200>;
-               ti,charge-current = <650>;
+               ti,charge-current = <950>;
                ti,termination-current = <100>;
                ti,resistor-sense = <68>;
 
index 7327fce87808d3b335e510291597c9e36a467d25..cf2480dce2853aa5799aae4b1e941311745628ef 100644 (file)
@@ -336,6 +336,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
 CONFIG_USB_SERIAL_OPTION=m
 CONFIG_USB_TEST=m
 CONFIG_USB_EHSET_TEST_FIXTURE=m
+CONFIG_USB_ONBOARD_DEV=y
 CONFIG_NOP_USB_XCEIV=y
 CONFIG_USB_MXS_PHY=y
 CONFIG_USB_GADGET=y
index 091e1840933cf2c61ab8c859a2474a7ca106cc00..56925adfe8422921a770b553aa77453843606818 100644 (file)
@@ -139,8 +139,8 @@ CONFIG_DRM_FBDEV_EMULATION=y
 CONFIG_DRM_RCAR_DU=y
 # CONFIG_DRM_RCAR_USE_MIPI_DSI is not set
 CONFIG_DRM_SHMOBILE=y
-CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
+CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_DISPLAY_CONNECTOR=y
 CONFIG_DRM_LVDS_CODEC=y
 CONFIG_DRM_SII902X=y
@@ -235,3 +235,4 @@ CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DEBUG_FS=y
+CONFIG_ARM_DEBUG_WX=y
index bddc82f789421191b10d5f6e00763bd53b215b7e..a83d29fed175630da96430c3d77056ff6d188a27 100644 (file)
@@ -110,6 +110,7 @@ CONFIG_DRM_PANEL_LVDS=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DRM_DW_HDMI=y
 CONFIG_DRM_LIMA=y
 CONFIG_FB_SIMPLE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
index a86a1d4f34618ce3a5b91157d209f8b879cb47ae..93afd1005b43c9ed7cc97c410b792c1fa877a38d 100644 (file)
@@ -127,6 +127,10 @@ cpu_resume_after_mmu:
        instr_sync
 #endif
        bl      cpu_init                @ restore the und/abt/irq banked regs
+#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
+       mov     r0, sp
+       bl      kasan_unpoison_task_stack_below
+#endif
        mov     r0, #0                  @ return zero on success
        ldmfd   sp!, {r4 - r11, pc}
 ENDPROC(cpu_resume_after_mmu)
index 25893d1091903fae1eb392c3b648117b366fb36a..b68cb86dbe4cf9c8291c21504d861c172ba2f667 100644 (file)
@@ -437,6 +437,7 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc,
 {
        *pmu_mmdc = (struct mmdc_pmu) {
                .pmu = (struct pmu) {
+                       .parent         = dev,
                        .task_ctx_nr    = perf_invalid_context,
                        .attr_groups    = attr_groups,
                        .event_init     = mmdc_pmu_event_init,
index 0297e302d7bc862736e8429dd08a69c257ab4d34..09bf366d05ff7953f5eb4e5d76fed7619a152831 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/irq.h>
 #include <linux/leds.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
@@ -55,12 +56,9 @@ static struct gpio_led d2net_leds[] = {
        {
                .name = "d2net:blue:sata",
                .default_trigger = "default-on",
-               .gpio = D2NET_GPIO_BLUE_LED_OFF,
-               .active_low = 1,
        },
        {
                .name = "d2net:red:fail",
-               .gpio = D2NET_GPIO_RED_LED,
        },
 };
 
@@ -77,6 +75,17 @@ static struct platform_device d2net_gpio_leds = {
        },
 };
 
+static struct gpiod_lookup_table d2net_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", D2NET_GPIO_BLUE_LED_OFF, NULL,
+                               0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", D2NET_GPIO_RED_LED, NULL,
+                               1, GPIO_ACTIVE_HIGH),
+               { },
+       },
+};
+
 static void __init d2net_gpio_leds_init(void)
 {
        int err;
@@ -91,6 +100,7 @@ static void __init d2net_gpio_leds_init(void)
        if (err)
                pr_err("d2net: failed to configure blue LED blink GPIO\n");
 
+       gpiod_add_lookup_table(&d2net_leds_gpio_table);
        platform_device_register(&d2net_gpio_leds);
 }
 
index d69259b6b60d64a17c123942183b3fd0808d689c..062109efa0ecc680516d1d2d4ad35290fe2d65b1 100644 (file)
@@ -14,6 +14,7 @@
  *
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -254,37 +255,64 @@ error_fail:
 static struct gpio_led dns323ab_leds[] = {
        {
                .name = "power:blue",
-               .gpio = DNS323_GPIO_LED_POWER2,
                .default_trigger = "default-on",
        }, {
                .name = "right:amber",
-               .gpio = DNS323_GPIO_LED_RIGHT_AMBER,
-               .active_low = 1,
        }, {
                .name = "left:amber",
-               .gpio = DNS323_GPIO_LED_LEFT_AMBER,
-               .active_low = 1,
        },
 };
 
+static struct gpiod_lookup_table dns323a1_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL,
+                               0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL,
+                               1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL,
+                               2, GPIO_ACTIVE_LOW),
+               { },
+       },
+};
+
+/* B1 is the same but power LED is active high */
+static struct gpiod_lookup_table dns323b1_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_POWER2, NULL,
+                               0, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_RIGHT_AMBER, NULL,
+                               1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323_GPIO_LED_LEFT_AMBER, NULL,
+                               2, GPIO_ACTIVE_LOW),
+               { },
+       },
+};
 
 static struct gpio_led dns323c_leds[] = {
        {
                .name = "power:blue",
-               .gpio = DNS323C_GPIO_LED_POWER,
                .default_trigger = "timer",
-               .active_low = 1,
        }, {
                .name = "right:amber",
-               .gpio = DNS323C_GPIO_LED_RIGHT_AMBER,
-               .active_low = 1,
        }, {
                .name = "left:amber",
-               .gpio = DNS323C_GPIO_LED_LEFT_AMBER,
-               .active_low = 1,
        },
 };
 
+static struct gpiod_lookup_table dns323c_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_POWER, NULL,
+                               0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_RIGHT_AMBER, NULL,
+                               1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", DNS323C_GPIO_LED_LEFT_AMBER, NULL,
+                               2, GPIO_ACTIVE_LOW),
+               { },
+       },
+};
 
 static struct gpio_led_platform_data dns323ab_led_data = {
        .num_leds       = ARRAY_SIZE(dns323ab_leds),
@@ -621,16 +649,21 @@ static void __init dns323_init(void)
                /* The 5181 power LED is active low and requires
                 * DNS323_GPIO_LED_POWER1 to also be low.
                 */
-                dns323ab_leds[0].active_low = 1;
-                gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
-                gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
-               fallthrough;
+               gpiod_add_lookup_table(&dns323a1_leds_gpio_table);
+               gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
+               gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
+               i2c_register_board_info(0, dns323ab_i2c_devices,
+                                       ARRAY_SIZE(dns323ab_i2c_devices));
+
+               break;
        case DNS323_REV_B1:
+               gpiod_add_lookup_table(&dns323b1_leds_gpio_table);
                i2c_register_board_info(0, dns323ab_i2c_devices,
                                ARRAY_SIZE(dns323ab_i2c_devices));
                break;
        case DNS323_REV_C1:
                /* Hookup LEDs & Buttons */
+               gpiod_add_lookup_table(&dns323c_leds_gpio_table);
                dns323_gpio_leds.dev.platform_data = &dns323c_led_data;
                dns323_button_device.dev.platform_data = &dns323c_button_data;
 
index 2bf8ec75e9089b85d82f3abfd51cb722a641b17e..b7327a61283531bef0a53546e623b76fb7968698 100644 (file)
@@ -8,6 +8,7 @@
  * License, or (at your option) any later version.
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -139,34 +140,45 @@ static struct i2c_board_info __initdata mv2120_i2c_rtc = {
 static struct gpio_led mv2120_led_pins[] = {
        {
                .name                   = "mv2120:blue:health",
-               .gpio                   = 0,
        },
        {
                .name                   = "mv2120:red:health",
-               .gpio                   = 1,
        },
        {
                .name                   = "mv2120:led:bright",
-               .gpio                   = 4,
                .default_trigger        = "default-on",
        },
        {
                .name                   = "mv2120:led:dimmed",
-               .gpio                   = 5,
        },
        {
                .name                   = "mv2120:red:sata0",
-               .gpio                   = 8,
-               .active_low             = 1,
        },
        {
                .name                   = "mv2120:red:sata1",
-               .gpio                   = 9,
-               .active_low             = 1,
        },
 
 };
 
+static struct gpiod_lookup_table mv2120_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", 0, NULL,
+                               0, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", 1, NULL,
+                               1, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", 4, NULL,
+                               2, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", 5, NULL,
+                               3, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", 8, NULL,
+                               4, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", 9, NULL,
+                               5, GPIO_ACTIVE_LOW),
+               { },
+       },
+};
+
 static struct gpio_led_platform_data mv2120_led_data = {
        .leds           = mv2120_led_pins,
        .num_leds       = ARRAY_SIZE(mv2120_led_pins),
@@ -219,6 +231,7 @@ static void __init mv2120_init(void)
                        gpio_free(MV2120_GPIO_RTC_IRQ);
        }
        i2c_register_board_info(0, &mv2120_i2c_rtc, 1);
+       gpiod_add_lookup_table(&mv2120_leds_gpio_table);
        platform_device_register(&mv2120_leds);
 
        /* register mv2120 specific power-off method */
index 695cc683cd8337efb2506d66f924a4a66ca32a18..6ad9740b426b633dca6adaf07c3760c68bbbdfbd 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/i2c.h>
 #include <linux/ata_platform.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/delay.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -214,19 +215,30 @@ err_free_1:
 static struct gpio_led net2big_leds[] = {
        {
                .name = "net2big:red:power",
-               .gpio = NET2BIG_GPIO_PWR_RED_LED,
        },
        {
                .name = "net2big:blue:power",
-               .gpio = NET2BIG_GPIO_PWR_BLUE_LED,
        },
        {
                .name = "net2big:red:sata0",
-               .gpio = NET2BIG_GPIO_SATA0_RED_LED,
        },
        {
                .name = "net2big:red:sata1",
-               .gpio = NET2BIG_GPIO_SATA1_RED_LED,
+       },
+};
+
+static struct gpiod_lookup_table net2big_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_RED_LED, NULL,
+                               0, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_BLUE_LED, NULL,
+                               1, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA0_RED_LED, NULL,
+                               2, GPIO_ACTIVE_HIGH),
+               GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA1_RED_LED, NULL,
+                               3, GPIO_ACTIVE_HIGH),
+               { },
        },
 };
 
@@ -282,6 +294,7 @@ static void __init net2big_gpio_leds_init(void)
        if (err)
                pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
 
+       gpiod_add_lookup_table(&net2big_leds_gpio_table);
        platform_device_register(&net2big_gpio_leds);
 }
 
index 6f60dc1dfa22891d82a430db5829c18c8e9b14b0..8131982c10d97e0a477b6266fd0ffdcf10e22139 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 2008  Martin Michlmayr <tbm@cyrius.com>
  */
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
@@ -168,20 +169,27 @@ static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
 static struct gpio_led ts409_led_pins[] = {
        {
                .name           = "ts409:red:sata1",
-               .gpio           = 4,
-               .active_low     = 1,
        }, {
                .name           = "ts409:red:sata2",
-               .gpio           = 5,
-               .active_low     = 1,
        }, {
                .name           = "ts409:red:sata3",
-               .gpio           = 6,
-               .active_low     = 1,
        }, {
                .name           = "ts409:red:sata4",
-               .gpio           = 7,
-               .active_low     = 1,
+       },
+};
+
+static struct gpiod_lookup_table ts409_leds_gpio_table = {
+       .dev_id = "leds-gpio",
+       .table = {
+               GPIO_LOOKUP_IDX("orion_gpio0", 4, NULL,
+                               0, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", 5, NULL,
+                               1, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", 6, NULL,
+                               2, GPIO_ACTIVE_LOW),
+               GPIO_LOOKUP_IDX("orion_gpio0", 7, NULL,
+                               3, GPIO_ACTIVE_LOW),
+               { },
        },
 };
 
@@ -300,6 +308,7 @@ static void __init qnap_ts409_init(void)
        if (qnap_ts409_i2c_rtc.irq == 0)
                pr_warn("qnap_ts409_init: failed to get RTC IRQ\n");
        i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
+       gpiod_add_lookup_table(&ts409_leds_gpio_table);
        platform_device_register(&ts409_leds);
 
        /* register tsx09 specific power-off method */
index 98145031586f14648d62169a276141df4a6993b2..ae21a9f78f9c2b9b6529fa52ab86ab1dfc34471c 100644 (file)
@@ -12,6 +12,7 @@ menuconfig ARCH_STM32
        select PINCTRL
        select RESET_CONTROLLER
        select STM32_EXTI
+       select STM32_FIREWALL
        help
          Support for STMicroelectronics STM32 processors.
 
index 1d672457d02ff3fcdd849c57c9108f94a8563886..72b5cd697f5d94b742fb59b98913c975838de871 100644 (file)
@@ -871,16 +871,11 @@ static inline void emit_a32_alu_r64(const bool is64, const s8 dst[],
 }
 
 /* dst = src (4 bytes)*/
-static inline void emit_a32_mov_r(const s8 dst, const s8 src, const u8 off,
-                                 struct jit_ctx *ctx) {
+static inline void emit_a32_mov_r(const s8 dst, const s8 src, struct jit_ctx *ctx) {
        const s8 *tmp = bpf2a32[TMP_REG_1];
        s8 rt;
 
        rt = arm_bpf_get_reg32(src, tmp[0], ctx);
-       if (off && off != 32) {
-               emit(ARM_LSL_I(rt, rt, 32 - off), ctx);
-               emit(ARM_ASR_I(rt, rt, 32 - off), ctx);
-       }
        arm_bpf_put_reg32(dst, rt, ctx);
 }
 
@@ -889,15 +884,15 @@ static inline void emit_a32_mov_r64(const bool is64, const s8 dst[],
                                  const s8 src[],
                                  struct jit_ctx *ctx) {
        if (!is64) {
-               emit_a32_mov_r(dst_lo, src_lo, 0, ctx);
+               emit_a32_mov_r(dst_lo, src_lo, ctx);
                if (!ctx->prog->aux->verifier_zext)
                        /* Zero out high 4 bytes */
                        emit_a32_mov_i(dst_hi, 0, ctx);
        } else if (__LINUX_ARM_ARCH__ < 6 &&
                   ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
                /* complete 8 byte move */
-               emit_a32_mov_r(dst_lo, src_lo, 0, ctx);
-               emit_a32_mov_r(dst_hi, src_hi, 0, ctx);
+               emit_a32_mov_r(dst_lo, src_lo, ctx);
+               emit_a32_mov_r(dst_hi, src_hi, ctx);
        } else if (is_stacked(src_lo) && is_stacked(dst_lo)) {
                const u8 *tmp = bpf2a32[TMP_REG_1];
 
@@ -917,17 +912,52 @@ static inline void emit_a32_mov_r64(const bool is64, const s8 dst[],
 static inline void emit_a32_movsx_r64(const bool is64, const u8 off, const s8 dst[], const s8 src[],
                                      struct jit_ctx *ctx) {
        const s8 *tmp = bpf2a32[TMP_REG_1];
-       const s8 *rt;
+       s8 rs;
+       s8 rd;
 
-       rt = arm_bpf_get_reg64(dst, tmp, ctx);
+       if (is_stacked(dst_lo))
+               rd = tmp[1];
+       else
+               rd = dst_lo;
+       rs = arm_bpf_get_reg32(src_lo, rd, ctx);
+       /* rs may be one of src[1], dst[1], or tmp[1] */
+
+       /* Sign extend rs if needed. If off == 32, lower 32-bits of src are moved to dst and sign
+        * extension only happens in the upper 64 bits.
+        */
+       if (off != 32) {
+               /* Sign extend rs into rd */
+               emit(ARM_LSL_I(rd, rs, 32 - off), ctx);
+               emit(ARM_ASR_I(rd, rd, 32 - off), ctx);
+       } else {
+               rd = rs;
+       }
+
+       /* Write rd to dst_lo
+        *
+        * Optimization:
+        * Assume:
+        * 1. dst == src and stacked.
+        * 2. off == 32
+        *
+        * In this case src_lo was loaded into rd(tmp[1]) but rd was not sign extended as off==32.
+        * So, we don't need to write rd back to dst_lo as they have the same value.
+        * This saves us one str instruction.
+        */
+       if (dst_lo != src_lo || off != 32)
+               arm_bpf_put_reg32(dst_lo, rd, ctx);
 
-       emit_a32_mov_r(dst_lo, src_lo, off, ctx);
        if (!is64) {
                if (!ctx->prog->aux->verifier_zext)
                        /* Zero out high 4 bytes */
                        emit_a32_mov_i(dst_hi, 0, ctx);
        } else {
-               emit(ARM_ASR_I(rt[0], rt[1], 31), ctx);
+               if (is_stacked(dst_hi)) {
+                       emit(ARM_ASR_I(tmp[0], rd, 31), ctx);
+                       arm_bpf_put_reg32(dst_hi, tmp[0], ctx);
+               } else {
+                       emit(ARM_ASR_I(dst_hi, rd, 31), ctx);
+               }
        }
 }
 
index 24335565bad5627d010755967941735bd83366e3..a028ea312378995935c53d40312ca015c225f5ab 100644 (file)
@@ -8,6 +8,13 @@ config ARCH_ACTIONS
        help
          This enables support for the Actions Semiconductor S900 SoC family.
 
+config ARCH_AIROHA
+       bool "Airoha SoC Support"
+       select ARM_PSCI
+       select HAVE_ARM_ARCH_TIMER
+       help
+         This enables support for the ARM64 based Airoha SoCs.
+
 config ARCH_SUNXI
        bool "Allwinner sunxi 64-bit SoC Family"
        select ARCH_HAS_RESET_CONTROLLER
@@ -305,6 +312,7 @@ config ARCH_STM32
        select ARM_SMC_MBOX
        select ARM_SCMI_PROTOCOL
        select COMMON_CLK_SCMI
+       select STM32_FIREWALL
        help
          This enables support for ARMv8 based STMicroelectronics
          STM32 family, including:
index 63e375cd9eb40eb4c39885031d6986e7b1311e60..bd54b516512978f1301ea7f54c10f0d853a68296 100644 (file)
@@ -24,7 +24,7 @@
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
-       memory@1,e0000000 {
+       memory@1e0000000 {
                device_type = "memory";
                reg = <0x1 0xe0000000 0x0 0x0>;
        };
index 21149b346a60ebe4eac4eabc0980cf38d08437a2..0db7b60b49a196eb4b6a5a9ef00f7d06bfe14775 100644 (file)
@@ -39,6 +39,7 @@ 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
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6-mini.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h313-tanix-tx1.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-cb1-manta.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-bigtreetech-pi.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h616-orangepi-zero2.dtb
@@ -47,3 +48,6 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-longanpi-3h.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero2w.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-orangepi-zero3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h618-transpeed-8k618-t.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-2024.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-plus.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h700-anbernic-rg35xx-h.dtb
index e6d5bc0f7a612b872e88ada600458a18e7defd61..d1f415acd7b557b17f97dfe1298b4be090fb6780 100644 (file)
@@ -53,7 +53,7 @@
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index 0af6dcdf7515a9f3d5008df8664bc40c2df979bd..dec9960a7440f5d1b5772bc8f9228e1472e6c18d 100644 (file)
@@ -41,7 +41,7 @@
                };
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&rtc CLK_OSC32K_FANOUT>;
                clock-names = "ext_clock";
index bfb806cf6d7ac95cdc39942c1e20a70334c714fd..fd3794678c331b8b980ec2d67f73bdf931e18298 100644 (file)
@@ -52,7 +52,7 @@
                status = "okay";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
        };
index 4f8529d5ac007079af2bf882a245acecba4b9d6c..c8303a66438de40989da4bc294b5c8441726a357 100644 (file)
@@ -68,7 +68,7 @@
                status = "okay";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 8 GPIO_ACTIVE_LOW>; /* PL8 */
                clocks = <&rtc CLK_OSC32K_FANOUT>;
index 50ed2e9f10ed0850d8242d4c71fb459ad9ff4edf..6c65d5bc16ba942740f5d3e8988c75b7195f6f55 100644 (file)
@@ -79,7 +79,7 @@
                enable-active-high;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
        };
index 87847116ab6d9b4d31b1f36d5584d9cf02645597..6eab61a12cd8f8ff41bc365b8e9817b29e696954 100644 (file)
        leds {
                compatible = "gpio-leds";
 
-               led-0 {
+               led0: led-0 {
                        function = LED_FUNCTION_INDICATOR;
                        color = <LED_COLOR_ID_BLUE>;
                        gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
+                       retain-state-suspended;
                };
 
-               led-1 {
+               led1: led-1 {
                        function = LED_FUNCTION_INDICATOR;
                        color = <LED_COLOR_ID_GREEN>;
                        gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
+                       retain-state-suspended;
                };
 
-               led-2 {
+               led2: led-2 {
                        function = LED_FUNCTION_INDICATOR;
                        color = <LED_COLOR_ID_RED>;
                        gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
+                       retain-state-suspended;
                };
        };
 
+       multi-led {
+               compatible = "leds-group-multicolor";
+               color = <LED_COLOR_ID_RGB>;
+               function = LED_FUNCTION_INDICATOR;
+               leds = <&led0>, <&led1>, <&led2>;
+       };
+
        reg_ps: ps-regulator {
                compatible = "regulator-fixed";
                regulator-name = "ps";
index 0a5607f73049e19ba9d3334b0907abbc7dd781f1..c6007df99938bac3ebac7e5dd89b3d4365942366 100644 (file)
@@ -98,7 +98,7 @@
                enable-active-high;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
                post-power-on-delay-ms = <200>;
index 1128030e4c25b5e23e68bed23603d1240460fc9c..b407e1dd08a737884efa0f3a83faf9b7e454d2fb 100644 (file)
@@ -74,7 +74,7 @@
                status = "okay";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
        };
index 57ac18738c995ba7cdb686b0adc1eb9549690110..ce4aa44c33534284cd458ec20424707b4c86018d 100644 (file)
        gpu_opp_table: opp-table-gpu {
                compatible = "operating-points-v2";
 
-               opp-120000000 {
-                       opp-hz = /bits/ 64 <120000000>;
-               };
-
-               opp-312000000 {
-                       opp-hz = /bits/ 64 <312000000>;
-               };
-
                opp-432000000 {
                        opp-hz = /bits/ 64 <432000000>;
                };
        };
 
-       osc24M: osc24M_clk {
+       osc24M: osc24M-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <24000000>;
                clock-output-names = "osc24M";
        };
 
-       osc32k: osc32k_clk {
+       osc32k: osc32k-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
                        };
 
                        trips {
-                               cpu_alert0: cpu_alert0 {
+                               cpu_alert0: cpu-alert0 {
                                        /* milliCelsius */
                                        temperature = <75000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu_alert1: cpu_alert1 {
+                               cpu_alert1: cpu-alert1 {
                                        /* milliCelsius */
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
 
-                               cpu_crit: cpu_crit {
+                               cpu_crit: cpu-crit {
                                        /* milliCelsius */
                                        temperature = <110000>;
                                        hysteresis = <2000>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts b/arch/arm64/boot/dts/allwinner/sun50i-h313-tanix-tx1.dts
new file mode 100644 (file)
index 0000000..bb2cde5
--- /dev/null
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2024 Arm Ltd.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       model = "Tanix TX1";
+       compatible = "oranth,tanix-tx1", "allwinner,sun50i-h616";
+
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &sdio_wifi;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               key {
+                       label = "hidden";
+                       linux,code = <BTN_0>;
+                       gpios = <&pio 7 9 GPIO_ACTIVE_LOW>; /* PH9 */
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-0 {
+                       function = LED_FUNCTION_POWER;
+                       color = <LED_COLOR_ID_BLUE>;
+                       gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */
+                       default-state = "on";
+               };
+       };
+
+       wifi_pwrseq: pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rtc CLK_OSC32K_FANOUT>;
+               clock-names = "ext_clock";
+               pinctrl-0 = <&x32clk_fanout_pin>;
+               pinctrl-names = "default";
+               reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+       };
+
+       reg_vcc5v: vcc5v {
+               /* board wide 5V supply directly from the DC input */
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ir {
+       status = "okay";
+};
+
+&mmc1 {
+       vmmc-supply = <&reg_dldo1>;
+       vqmmc-supply = <&reg_aldo1>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       sdio_wifi: wifi@1 {
+               reg = <1>;
+       };
+};
+
+&mmc2 {
+       vmmc-supply = <&reg_dldo1>;
+       vqmmc-supply = <&reg_aldo1>;
+       bus-width = <8>;
+       non-removable;
+       max-frequency = <100000000>;
+       cap-mmc-hw-reset;
+       mmc-ddr-1_8v;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&pio {
+       vcc-pc-supply = <&reg_aldo1>;
+       vcc-pf-supply = <&reg_dldo1>;
+       vcc-pg-supply = <&reg_aldo1>;
+       vcc-ph-supply = <&reg_dldo1>;
+       vcc-pi-supply = <&reg_dldo1>;
+};
+
+&r_i2c {
+       status = "okay";
+
+       axp313: pmic@36 {
+               compatible = "x-powers,axp313a";
+               reg = <0x36>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+
+               vin1-supply = <&reg_vcc5v>;
+               vin2-supply = <&reg_vcc5v>;
+               vin3-supply = <&reg_vcc5v>;
+
+               regulators {
+                       /* Supplies VCC-PLL, so needs to be always on. */
+                       reg_aldo1: aldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc1v8";
+                       };
+
+                       /* Supplies VCC-IO, so needs to be always on. */
+                       reg_dldo1: dldo1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc3v3";
+                       };
+
+                       reg_dcdc1: dcdc1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <990000>;
+                               regulator-name = "vdd-gpu-sys";
+                       };
+
+                       reg_dcdc2: dcdc2 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <810000>;
+                               regulator-max-microvolt = <1120000>;
+                               regulator-name = "vdd-cpu";
+                       };
+
+                       reg_dcdc3: dcdc3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "vdd-dram";
+                       };
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_ph_pins>;
+       status = "okay";
+};
+
+&usbotg {
+       dr_mode = "host";       /* USB A type receptable */
+       status = "okay";
+};
+
+&usbphy {
+       status = "okay";
+};
index 4c3921ac236cca2cacee1b6bfbddc3ee3827351f..b69032c4455754cbe9fae604761d3b640d1a78eb 100644 (file)
@@ -68,7 +68,7 @@
                states = <1100000 0>, <1300000 1>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                post-power-on-delay-ms = <200>;
index a3e040da38a0735d23c3fab1ffe01d48bba2f637..3a7ee44708a2051da23f883f26175157ba3067ad 100644 (file)
                states = <1100000 0x0>, <1300000 0x1>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */
                post-power-on-delay-ms = <200>;
        non-removable;
        status = "okay";
 
-       rtl8189etv: sdio_wifi@1 {
+       rtl8189etv: wifi@1 {
                reg = <1>;
        };
 };
index d7f8bad6bb9809eb9941b0ac6f1a6d56f4db5a9c..b699bb900e13bb6e2d293d227cefd893645ccb41 100644 (file)
@@ -85,7 +85,7 @@
                status = "okay";
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 2 14 GPIO_ACTIVE_LOW>; /* PC14 */
        };
index 7ec5ac850a0dc576a9680aac773ad9792387a9c6..ae85131aac9c730d2738cec1cdb930c5e3c55101 100644 (file)
@@ -97,7 +97,7 @@
         * Explicitly define the sdio device, so that we can add an ethernet
         * alias for it (which e.g. makes u-boot set a mac-address).
         */
-       rtl8189ftv: sdio_wifi@1 {
+       rtl8189ftv: wifi@1 {
                reg = <1>;
        };
 };
index 22530ace12d5a0c9f505f1a7c66d79e794b2c432..734481e998b8dd4b7efe319605dd8c9b64a86ed7 100644 (file)
@@ -52,7 +52,7 @@
                regulator-max-microvolt = <3300000>;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
                post-power-on-delay-ms = <200>;
index 381d58cea092d9f8dadfe6f37ba2caa52d700c1c..3be1e8c2fdb9cf1aa2a3d5403a99892a778b737b 100644 (file)
@@ -34,7 +34,7 @@
                };
        };
 
-       ext_osc32k: ext_osc32k_clk {
+       ext_osc32k: ext-osc32k-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
index 6fc65e8db2206810ae34b14f48916aed4b2f00b7..6c3bfe3d09d9a3582b4bbb996cfa5ba05bf54cc0 100644 (file)
@@ -33,7 +33,7 @@
                };
        };
 
-       ext_osc32k: ext_osc32k_clk {
+       ext_osc32k: ext-osc32k-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
index fb31dcb1cb6d772e9646898f0e9c96f985e34ea9..a3f65a45bd26635d29dafe785ec28641a1501a79 100644 (file)
@@ -11,7 +11,7 @@
                serial1 = &uart1; /* BT-UART */
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&rtc CLK_OSC32K_FANOUT>;
                clock-names = "ext_clock";
index 92745128fcfebdf6d1f85cb6605ac560e2aaa7ca..13b07141c3344b6949c618425fd571f05da85623 100644 (file)
@@ -32,7 +32,7 @@
                };
        };
 
-       ext_osc32k: ext_osc32k_clk {
+       ext_osc32k: ext-osc32k-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
index b710f1a0f53acb64df63bc3a442d429da455fda6..66fe03910d5e6b482e1a1a0fca3fa62050eaee83 100644 (file)
@@ -5,13 +5,13 @@
 
 #include "sun50i-h6-pine-h64.dts"
 
+/delete-node/ &reg_gmac_3v3;
+
 / {
        model = "Pine H64 model B";
        compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6";
 
-       /delete-node/ reg_gmac_3v3;
-
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */
                post-power-on-delay-ms = <200>;
index 1ffd68f43f875845f245e60d17e8c02f932ed88d..3910393be1f96c9f869b61fe3d16cecd8eeff0a9 100644 (file)
@@ -22,7 +22,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       ext_osc32k: ext_osc32k_clk {
+       ext_osc32k: ext-osc32k-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
index d11e5041bae9a470242e0226ecde743dd1b72fa7..8a8591c4e7dd6cf6aaca502ddb8c72fba110f513 100644 (file)
@@ -68,7 +68,7 @@
                status = "disabled";
        };
 
-       osc24M: osc24M_clk {
+       osc24M: osc24M-clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <24000000>;
index b2e85e52d1a12217e94cfd3b64b00b131075e76c..f8ecd7db486864ed7da75f6538193d118510ffe9 100644 (file)
                        };
 
                        i2c0_pins: i2c0-pins {
-                               pins = "PI6", "PI7";
+                               pins = "PI5", "PI6";
                                function = "i2c0";
                        };
 
                        #reset-cells = <1>;
                };
 
+               nmi_intc: interrupt-controller@7010320 {
+                       compatible = "allwinner,sun50i-h616-nmi",
+                                    "allwinner,sun9i-a80-nmi";
+                       reg = <0x07010320 0xc>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
                r_pio: pinctrl@7022000 {
                        compatible = "allwinner,sun50i-h616-r-pinctrl";
                        reg = <0x07022000 0x400>;
index ac0a2b7ea6f31089fba1bae1d76fbffba859320f..a1d0cac4d2441de231ed9b67e68f6926db045c7e 100644 (file)
@@ -41,7 +41,7 @@
                regulator-always-on;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&rtc CLK_OSC32K_FANOUT>;
                clock-names = "ext_clock";
index b6e3c169797f0514fa261bcbadbbe346b5f09a6b..c204dd43c7269149b01f1abc990a7d20c1943cb1 100644 (file)
@@ -42,7 +42,7 @@
                regulator-always-on;
        };
 
-       wifi_pwrseq: wifi_pwrseq {
+       wifi_pwrseq: pwrseq {
                compatible = "mmc-pwrseq-simple";
                reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
                post-power-on-delay-ms = <200>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-2024.dts
new file mode 100644 (file)
index 0000000..ee30584
--- /dev/null
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ */
+
+/dts-v1/;
+
+#include "sun50i-h616.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       model = "Anbernic RG35XX 2024";
+       chassis-type = "handset";
+       compatible = "anbernic,rg35xx-2024", "allwinner,sun50i-h700";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio_keys_gamepad: gpio-keys-gamepad {
+               compatible = "gpio-keys";
+
+               button-a {
+                       label = "Action-Pad A";
+                       gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; /* PA0 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_EAST>;
+               };
+
+               button-b {
+                       label = "Action-Pad B";
+                       gpios = <&pio 0 1 GPIO_ACTIVE_LOW>; /* PA1 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_SOUTH>;
+               };
+
+               button-down {
+                       label = "D-Pad Down";
+                       gpios = <&pio 4 0 GPIO_ACTIVE_LOW>; /* PE0 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_DPAD_DOWN>;
+               };
+
+               button-l1 {
+                       label = "Key L1";
+                       gpios = <&pio 0 10 GPIO_ACTIVE_LOW>; /* PA10 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_TL>;
+               };
+
+               button-l2 {
+                       label = "Key L2";
+                       gpios = <&pio 0 11 GPIO_ACTIVE_LOW>; /* PA11 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_TL2>;
+               };
+
+               button-left {
+                       label = "D-Pad left";
+                       gpios = <&pio 0 8 GPIO_ACTIVE_LOW>; /* PA8 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_DPAD_LEFT>;
+               };
+
+               button-menu {
+                       label = "Key Menu";
+                       gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_MODE>;
+               };
+
+               button-r1 {
+                       label = "Key R1";
+                       gpios = <&pio 0 12 GPIO_ACTIVE_LOW>; /* PA12 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_TR>;
+               };
+
+               button-r2 {
+                       label = "Key R2";
+                       gpios = <&pio 0 7 GPIO_ACTIVE_LOW>; /* PA7 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_TR2>;
+               };
+
+               button-right {
+                       label = "D-Pad Right";
+                       gpios = <&pio 0 9 GPIO_ACTIVE_LOW>; /* PA9 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_DPAD_RIGHT>;
+               };
+
+               button-select {
+                       label = "Key Select";
+                       gpios = <&pio 0 5 GPIO_ACTIVE_LOW>; /* PA5 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_SELECT>;
+               };
+               button-start {
+                       label = "Key Start";
+                       gpios = <&pio 0 4 GPIO_ACTIVE_LOW>; /* PA4 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_START>;
+               };
+
+               button-up {
+                       label = "D-Pad Up";
+                       gpios = <&pio 0 6 GPIO_ACTIVE_LOW>; /* PA6 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_DPAD_UP>;
+               };
+
+               button-x {
+                       label = "Action-Pad X";
+                       gpios = <&pio 0 3 GPIO_ACTIVE_LOW>; /* PA3 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_NORTH>;
+               };
+
+               button-y {
+                       label = "Action Pad Y";
+                       gpios = <&pio 0 2 GPIO_ACTIVE_LOW>; /* PA2 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <BTN_WEST>;
+               };
+       };
+
+       gpio-keys-volume {
+               compatible = "gpio-keys";
+               autorepeat;
+
+               button-vol-up {
+                       label = "Key Volume Up";
+                       gpios = <&pio 4 1 GPIO_ACTIVE_LOW>; /* PE1 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               button-vol-down {
+                       label = "Key Volume Down";
+                       gpios = <&pio 4 2 GPIO_ACTIVE_LOW>; /* PE2 */
+                       linux,input-type = <EV_KEY>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-0 {
+                       function = LED_FUNCTION_POWER;
+                       color = <LED_COLOR_ID_GREEN>;
+                       gpios = <&pio 8 12 GPIO_ACTIVE_HIGH>; /* PI12 */
+                       default-state = "on";
+               };
+       };
+
+       reg_vcc5v: regulator-vcc5v { /* USB-C power input */
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_dcdc1>;
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_cldo3>;
+       disable-wp;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;  /* PF6 */
+       bus-width = <4>;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&pio {
+       vcc-pa-supply = <&reg_cldo3>;
+       vcc-pc-supply = <&reg_cldo3>;
+       vcc-pe-supply = <&reg_cldo3>;
+       vcc-pf-supply = <&reg_cldo3>;
+       vcc-pg-supply = <&reg_aldo4>;
+       vcc-ph-supply = <&reg_cldo3>;
+       vcc-pi-supply = <&reg_cldo3>;
+};
+
+&r_rsb {
+       status = "okay";
+
+       axp717: pmic@3a3 {
+               compatible = "x-powers,axp717";
+               reg = <0x3a3>;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               interrupt-parent = <&nmi_intc>;
+               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+               vin1-supply = <&reg_vcc5v>;
+               vin2-supply = <&reg_vcc5v>;
+               vin3-supply = <&reg_vcc5v>;
+               vin4-supply = <&reg_vcc5v>;
+
+               regulators {
+                       reg_dcdc1: dcdc1 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-name = "vdd-cpu";
+                       };
+
+                       reg_dcdc2: dcdc2 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <940000>;
+                               regulator-max-microvolt = <940000>;
+                               regulator-name = "vdd-gpu-sys";
+                       };
+
+                       reg_dcdc3: dcdc3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-name = "vdd-dram";
+                       };
+
+                       reg_aldo1: aldo1 {
+                               /* 1.8v - unused */
+                       };
+
+                       reg_aldo2: aldo2 {
+                               /* 1.8v - unused */
+                       };
+
+                       reg_aldo3: aldo3 {
+                               /* 1.8v - unused */
+                       };
+
+                       reg_aldo4: aldo4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-pg";
+                       };
+
+                       reg_bldo1: bldo1 {
+                               /* 1.8v - unused */
+                       };
+
+                       reg_bldo2: bldo2 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc-pll";
+                       };
+
+                       reg_bldo3: bldo3 {
+                               /* 2.8v - unused */
+                       };
+
+                       reg_bldo4: bldo4 {
+                               /* 1.2v - unused */
+                       };
+
+                       reg_cldo1: cldo1 {
+                               /* 3.3v - audio codec - not yet implemented */
+                       };
+
+                       reg_cldo2: cldo2 {
+                               /* 3.3v - unused */
+                       };
+
+                       reg_cldo3: cldo3 {
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-io";
+                       };
+
+                       reg_cldo4: cldo4 {
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc-wifi";
+                       };
+
+                       reg_boost: boost {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5200000>;
+                               regulator-name = "boost";
+                       };
+
+                       reg_cpusldo: cpusldo {
+                               /* unused */
+                       };
+               };
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_ph_pins>;
+       status = "okay";
+};
+
+/* the AXP717 has USB type-C role switch functionality, not yet described by the binding */
+&usbotg {
+       dr_mode = "peripheral";   /* USB type-C receptable */
+       status = "okay";
+};
+
+&usbphy {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-h.dts
new file mode 100644 (file)
index 0000000..6303625
--- /dev/null
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ * Copyright (C) 2024 Chris Morgan <macroalpha82@gmail.com>.
+ */
+
+#include "sun50i-h700-anbernic-rg35xx-plus.dts"
+
+/ {
+       model = "Anbernic RG35XX H";
+       compatible = "anbernic,rg35xx-h", "allwinner,sun50i-h700";
+};
+
+&gpio_keys_gamepad {
+       button-thumbl {
+               label = "GPIO Thumb Left";
+               gpios = <&pio 4 8 GPIO_ACTIVE_LOW>; /* PE8 */
+               linux,input-type = <EV_KEY>;
+               linux,code = <BTN_THUMBL>;
+       };
+
+       button-thumbr {
+               label = "GPIO Thumb Right";
+               gpios = <&pio 4 9 GPIO_ACTIVE_LOW>; /* PE9 */
+               linux,input-type = <EV_KEY>;
+               linux,code = <BTN_THUMBR>;
+       };
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h700-anbernic-rg35xx-plus.dts
new file mode 100644 (file)
index 0000000..60a8e49
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) 2024 Ryan Walklin <ryan@testtoast.com>.
+ */
+
+#include "sun50i-h700-anbernic-rg35xx-2024.dts"
+
+/ {
+       model = "Anbernic RG35XX Plus";
+       compatible = "anbernic,rg35xx-plus", "allwinner,sun50i-h700";
+
+       wifi_pwrseq: pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rtc CLK_OSC32K_FANOUT>;
+               clock-names = "ext_clock";
+               pinctrl-0 = <&x32clk_fanout_pin>;
+               pinctrl-names = "default";
+               post-power-on-delay-ms = <200>;
+               reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */
+       };
+};
+
+/* SDIO WiFi RTL8821CS */
+&mmc1 {
+       vmmc-supply = <&reg_cldo4>;
+       vqmmc-supply = <&reg_aldo4>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       sdio_wifi: wifi@1 {
+               reg = <1>;
+               interrupt-parent = <&pio>;
+               interrupts = <6 15 IRQ_TYPE_LEVEL_LOW>; /* PG15 */
+               interrupt-names = "host-wake";
+       };
+};
+
+/* Bluetooth RTL8821CS */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "realtek,rtl8821cs-bt", "realtek,rtl8723bs-bt";
+               device-wake-gpios = <&pio 6 17 GPIO_ACTIVE_HIGH>; /* PG17 */
+               enable-gpios = <&pio 6 19 GPIO_ACTIVE_HIGH>; /* PG19 */
+               host-wake-gpios = <&pio 6 16 GPIO_ACTIVE_HIGH>; /* PG16 */
+       };
+};
index 072fe20cfca087635697d2b62171bcc854bf88b6..cbbc53c4792180d7b8ee75e7d25d79fc1caca5aa 100644 (file)
@@ -79,7 +79,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <0 170 4>,
                             <0 171 4>,
                             <0 172 4>,
index dbf2dce8d1d68a5225311bf330704e9f6d1ead40..da9de4986660f2d7c3d325a7850812cf0ae04d21 100644 (file)
@@ -39,6 +39,7 @@
 / {
        model = "Annapurna Labs Alpine v2";
        compatible = "al,alpine-v2";
+       interrupt-parent = <&gic>;
        #address-cells = <2>;
        #size-cells = <2>;
 
                clock-frequency = <1000000>;
        };
 
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
+
+       pmu {
+               compatible = "arm,cortex-a57-pmu";
+               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                interrupt-parent = <&gic>;
                ranges;
 
-               timer {
-                       compatible = "arm,armv8-timer";
-                       interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
-                                    <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
-                                    <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-                                    <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-               };
-
-               pmu {
-                       compatible = "arm,armv8-pmuv3";
-                       interrupts = <GIC_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: interrupt-controller@f0200000 {
                        compatible = "arm,gic-v3";
                        reg = <0x0 0xf0200000 0x0 0x10000>,     /* GIC Dist */
                        al,msi-num-spis = <160>;
                };
 
-               io-fabric {
+               io-fabric@fc000000 {
                        compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
index 3ea178acdddfe2072352283f47318f0f75808c4f..8b6156b5af659f864ef9506dfb8d14cb5d6caf9c 100644 (file)
                        next-level-cache = <&cluster3_l2>;
                };
 
-               cluster0_l2: cache@0 {
+               cluster0_l2: cache-0 {
                        compatible = "cache";
                        cache-size = <0x200000>;
                        cache-line-size = <64>;
                        cache-unified;
                };
 
-               cluster1_l2: cache@100 {
+               cluster1_l2: cache-100 {
                        compatible = "cache";
                        cache-size = <0x200000>;
                        cache-line-size = <64>;
                        cache-unified;
                };
 
-               cluster2_l2: cache@200 {
+               cluster2_l2: cache-200 {
                        compatible = "cache";
                        cache-size = <0x200000>;
                        cache-line-size = <64>;
                        cache-unified;
                };
 
-               cluster3_l2: cache@300 {
+               cluster3_l2: cache-300 {
                        compatible = "cache";
                        cache-size = <0x200000>;
                        cache-line-size = <64>;
                #size-cells = <2>;
                ranges;
 
-               gic: interrupt-controller@f0000000 {
+               gic: interrupt-controller@f0800000 {
                        compatible = "arm,gic-v3";
                        #interrupt-cells = <3>;
                        interrupt-controller;
                        interrupt-parent = <&gic>;
                };
 
-               io-fabric {
+               io-fabric@fc000000 {
                        compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
index 568bcc39ce9f15eeb9f381c387b88878f0e91402..6c1b7b8fe35473d6a34883a48fdbe32db64d0d8b 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2023 Advanced Micro Devices, Inc.
  */
index 46b6c6783f58a387110537bd5e304ab586eccec0..d12e9a7b5587a6ed1b9f87b0b272b28d2bbade3f 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2022 Advanced Micro Devices, Inc.
  */
index c3f4da2f7449c44dcdba050f7afefb174f77baa6..20b0fa0807a155569382d4cd0d61b06b81f70043 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Device Tree file for AMD Pensando Elba Board.
  *
index cf761a05a81fa5aaf79a1831fcfa8f7e0ac69360..6ea2d777c8c94e89bd42577e216ff2b6bd97a14f 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2023 Advanced Micro Devices, Inc.
  */
index 674890cf2a341121fef67be77a5eeeb19b9fc23d..758bce0a0b2a5d7565d07d73d213a443cd8ba24e 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 /*
  * Copyright 2020-2022 Advanced Micro Devices, Inc.
  */
index 2e8069002ec1d5dc4da7e453bad76b34b7a019f1..6e05cf1a3df653772c166d21e8b13f9268088c31 100644 (file)
@@ -15,7 +15,7 @@
 
        chosen { };
 
-       memory {
+       memory@100000000 {
                device_type = "memory";
                reg = < 0x1 0x00000000 0x0 0x80000000 >;
        };
index 033e10e12b18557b87835ec6e2b4233dc435a8e1..e7644cddf06ff93884b8be592cfcf4446acf05f7 100644 (file)
@@ -15,7 +15,7 @@
 
        chosen { };
 
-       memory {
+       memory@100000000 {
                device_type = "memory";
                reg = < 0x1 0x00000000 0x0 0x80000000 >; /* Updated by bootloader */
        };
index 65ebac3082e208e4781d3d21cba3d80892d1c7e3..ea5721ea02f0e6d69f11998ef2e22e482c40a015 100644 (file)
                };
        };
 
+       refclk: refclk {
+               compatible = "fixed-clock";
+               #clock-cells = <1>;
+               clock-frequency = <100000000>;
+               clock-output-names = "refclk";
+       };
+
        pmu {
                compatible = "arm,armv8-pmuv3";
                interrupts = <1 12 0xff04>;
                        #size-cells = <2>;
                        ranges;
 
-                       refclk: refclk {
-                               compatible = "fixed-clock";
-                               #clock-cells = <1>;
-                               clock-frequency = <100000000>;
-                               clock-output-names = "refclk";
-                       };
-
                        pmdpll: pmdpll@170000f0 {
                                compatible = "apm,xgene-pcppll-v2-clock";
                                #clock-cells = <1>;
index 988928c60f1515f5dd4551348358574cfb025572..532401bc9c6607c562068f541d9ca295f1691b3c 100644 (file)
                interrupts = <1 9 0xf04>;       /* GIC Maintenence IRQ */
        };
 
+       refclk: refclk {
+               compatible = "fixed-clock";
+               #clock-cells = <1>;
+               clock-frequency = <100000000>;
+               clock-output-names = "refclk";
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <1 0 0xff08>,      /* Secure Phys IRQ */
        };
 
        pmu {
-               compatible = "apm,potenza-pmu", "arm,armv8-pmuv3";
+               compatible = "apm,potenza-pmu";
                interrupts = <1 12 0xff04>;
        };
 
                        #address-cells = <2>;
                        #size-cells = <2>;
                        ranges;
-                       refclk: refclk {
-                               compatible = "fixed-clock";
-                               #clock-cells = <1>;
-                               clock-frequency = <100000000>;
-                               clock-output-names = "refclk";
-                       };
 
                        pcppll: pcppll@17000100 {
                                compatible = "apm,xgene-pcppll-clock";
index b897f5542c0a1c9b2adb72797327adf83bea90b9..98ed2b329ed61204672fe011a1b242c4d8ac5690 100644 (file)
                        };
                };
 
-               big_cluster_thermal_zone: big-cluster-thermal {
+               big_cluster_thermal_zone: big-cl-thermal {
                        polling-delay = <1000>;
                        polling-delay-passive = <100>;
                        thermal-sensors = <&scpi_sensors0 21>;
                        status = "disabled";
                };
 
-               little_cluster_thermal_zone: little-cluster-thermal {
+               little_cluster_thermal_zone: little-cl-thermal {
                        polling-delay = <1000>;
                        polling-delay-passive = <100>;
                        thermal-sensors = <&scpi_sensors0 22>;
index 31929e2377d8a41392ae159a2d0402d2d94bcd4a..f38c5b6ef65777366e2f3b086e3ba016ea450064 100644 (file)
                        thermal-sensors = <&scmi_sensors0 3>;
                };
 
-               big-cluster-thermal {
+               big-cl-thermal {
                        thermal-sensors = <&scmi_sensors0 21>;
                };
 
-               little-cluster-thermal {
+               little-cl-thermal {
                        thermal-sensors = <&scmi_sensors0 22>;
                };
 
index 8db4243a494728fed2833d60edfb94e282c66ed0..9115c99d0dc02c8d47eb0f3ac2e0cdfcfa3bfc78 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
        };
index e01cf4f540770cc24b92c0aa6051ced0e473206d..8b924812322cde7af413263ea0aede5612c075df 100644 (file)
                        reg-names = "nand", "nand-int-base";
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "nand_ctlrdy";
+                       brcm,wp-not-connected;
                        status = "disabled";
 
                        nandcs: nand@0 {
index 030ffa5364fbc1245abf693185d4520d59e72f65..e5b37643296bf40d035d46bf5198cce8a3176b58 100644 (file)
@@ -34,7 +34,6 @@
 };
 
 &nand_controller {
-       brcm,wp-not-connected;
        status = "okay";
 };
 
index dec5a110f1e80d5859e3d7c0cb306e84fed31fd5..f43cfe66b6af65fa5d0f6c5bb09c1409ca91711e 100644 (file)
@@ -50,7 +50,7 @@
                bootargs = "earlycon=uart8250,mmio32,0x66130000";
        };
 
-       memory {
+       memory@80000000 {
                device_type = "memory";
                reg = <0x00000000 0x80000000 0x00000000 0x40000000>;
        };
index 1d314f17bbdda9c9f1a49372a3a7f8088037e80b..c50df1d027974ffa73c0b3cda84c6611e0595b83 100644 (file)
@@ -47,7 +47,7 @@
                bootargs = "earlycon=uart8250,mmio32,0x66130000";
        };
 
-       memory {
+       memory@80000000 {
                device_type = "memory";
                reg = <0x00000000 0x80000000 0x00000001 0x00000000>;
        };
index 896d1f33b5b6173e3b4b701d4e08f4ad277856e0..cfd9fd23a1c2a69968a4412ca201b19885403def 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a57-pmu";
                interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
index d8516ec0dae7450e2c5e81f0bddf8ffdeba2bb5e..857fa427e195f0a0930685db348a4e5066ae20ec 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a72-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index 8ad31dee11a3c10e20e8d32ad6530d2f56dda9c0..cc860a80af516c903a4a65c8faf01c21c5c0a5cc 100644 (file)
        };
 
        pmu {
-               compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3";
+               compatible = "cavium,thunder-pmu";
                interrupts = <1 7 4>;
        };
 
+       refclk50mhz: refclk50mhz {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <50000000>;
+               clock-output-names = "refclk50mhz";
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
 
-               refclk50mhz: refclk50mhz {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-                       clock-frequency = <50000000>;
-                       clock-output-names = "refclk50mhz";
-               };
-
-               gic0: interrupt-controller@8010,00000000 {
+               gic0: interrupt-controller@801000000000 {
                        compatible = "arm,gic-v3";
                        #interrupt-cells = <3>;
                        #address-cells = <2>;
                        };
                };
 
-               uaa0: serial@87e0,24000000 {
+               uaa0: serial@87e024000000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x87e0 0x24000000 0x0 0x1000>;
                        interrupts = <1 21 4>;
                        clock-names = "apb_pclk";
                };
 
-               uaa1: serial@87e0,25000000 {
+               uaa1: serial@87e025000000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x87e0 0x25000000 0x0 0x1000>;
                        interrupts = <1 22 4>;
index d005e1e79c3d284c9fc902bbe37f616907f5e29c..89fc4107a0c47ddb74dfc4ee9aec2664aaf02a36 100644 (file)
@@ -14,7 +14,7 @@
        model = "Cavium ThunderX2 CN99XX";
        compatible = "cavium,thunderx2-cn9900", "brcm,vulcan-soc";
 
-       memory {
+       memory@80000000 {
                device_type = "memory";
                reg = <0x00000000 0x80000000 0x0 0x80000000>,  /* 2G @ 2G  */
                      <0x00000008 0x80000000 0x0 0x80000000>;  /* 2G @ 34G */
index 3419bd252696c41e63735a40107822f4517b1296..6dfe78a7d4ab3e38fd8235e5af0f828a4eb47678 100644 (file)
@@ -83,7 +83,7 @@
        };
 
        pmu {
-               compatible = "brcm,vulcan-pmu", "arm,armv8-pmuv3";
+               compatible = "brcm,vulcan-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; /* PMU overflow */
        };
 
 
                /* ECAM at 0x3000_0000 - 0x4000_0000 */
                reg = <0x0 0x30000000  0x0 0x10000000>;
-               reg-names = "PCI ECAM";
 
                /*
                 * PCI ranges:
index 7fbbec04bff037a6f36757397f6bea4504cc385f..0b9053b9b2b500f06e0ea9bc472cc4d15a335d01 100644 (file)
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi0_bus>;
                        num-cs = <1>;
+                       fifo-depth = <256>;
                        status = "disabled";
                };
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi1_bus>;
                        num-cs = <1>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi2_bus>;
                        num-cs = <1>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi3_bus>;
                        num-cs = <1>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&spi4_bus>;
                        num-cs = <1>;
+                       fifo-depth = <64>;
                        status = "disabled";
                };
 
index 2ba67c3d068116041aa74b758743bf11101fa335..0706c8534cebf242df06af57c531b06a51307cb2 100644 (file)
@@ -93,6 +93,8 @@
                        compatible = "arm,cortex-a55";
                        reg = <0x0>;
                        enable-method = "psci";
+                       clocks = <&cmu_cpucl0 CLK_CLUSTER0_SCLK>;
+                       clock-names = "cluster0_clk";
                };
                cpu1: cpu@1 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a55";
                        reg = <0x100>;
                        enable-method = "psci";
+                       clocks = <&cmu_cpucl1 CLK_CLUSTER1_SCLK>;
+                       clock-names = "cluster1_clk";
                };
                cpu5: cpu@101 {
                        device_type = "cpu";
                                      "dout_peri_uart", "dout_peri_ip";
                };
 
+               cmu_cpucl1: clock-controller@10800000 {
+                       compatible = "samsung,exynos850-cmu-cpucl1";
+                       reg = <0x10800000 0x8000>;
+                       #clock-cells = <1>;
+
+                       clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL1_SWITCH>,
+                                <&cmu_top CLK_DOUT_CPUCL1_DBG>;
+                       clock-names = "oscclk", "dout_cpucl1_switch",
+                                     "dout_cpucl1_dbg";
+               };
+
+               cmu_cpucl0: clock-controller@10900000 {
+                       compatible = "samsung,exynos850-cmu-cpucl0";
+                       reg = <0x10900000 0x8000>;
+                       #clock-cells = <1>;
+
+                       clocks = <&oscclk>, <&cmu_top CLK_DOUT_CPUCL0_SWITCH>,
+                                <&cmu_top CLK_DOUT_CPUCL0_DBG>;
+                       clock-names = "oscclk", "dout_cpucl0_switch",
+                                     "dout_cpucl0_dbg";
+               };
+
                cmu_g3d: clock-controller@11400000 {
                        compatible = "samsung,exynos850-cmu-g3d";
                        reg = <0x11400000 0x8000>;
index c871a2f49fda86ffb309f94f5b65701d3d58eb48..0248329da49a6393d2ec4a2e58b1498143419cbc 100644 (file)
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
                                num-cs = <1>;
                                #address-cells = <1>;
                                #size-cells = <0>;
+                               fifo-depth = <64>;
                                status = "disabled";
                        };
 
index 6ccade2c8cb489a347a582a77803657bb886ffb6..5e8ffe065081b7260f2b2d89de2006d9183083c2 100644 (file)
@@ -29,8 +29,8 @@
 
        gpio-keys {
                compatible = "gpio-keys";
-               pinctrl-names = "default";
                pinctrl-0 = <&key_voldown>, <&key_volup>, <&key_power>;
+               pinctrl-names = "default";
 
                button-vol-down {
                        label = "KEY_VOLUMEDOWN";
                        wakeup-source;
                };
        };
+
+       /* TODO: Remove this once PMIC is implemented  */
+       reg_placeholder: regulator-0 {
+               compatible = "regulator-fixed";
+               regulator-name = "placeholder_reg";
+       };
+
+       /* TODO: Remove this once S2MPG11 slave PMIC is implemented  */
+       ufs_0_fixed_vcc_reg: regulator-1 {
+               compatible = "regulator-fixed";
+               regulator-name = "ufs-vcc";
+               gpio = <&gpp0 1 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               enable-active-high;
+       };
 };
 
 &ext_24_5m {
 };
 
 &serial_0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_bus>;
+       status = "okay";
+};
+
+&ufs_0 {
+       status = "okay";
+       vcc-supply = <&ufs_0_fixed_vcc_reg>;
+};
+
+&ufs_0_phy {
+       status = "okay";
+};
+
+&usbdrd31 {
+       status = "okay";
+       vdd10-supply = <&reg_placeholder>;
+       vdd33-supply = <&reg_placeholder>;
+};
+
+&usbdrd31_dwc3 {
+       dr_mode = "otg";
+       usb-role-switch;
+       role-switch-default-mode = "peripheral";
+       maximum-speed = "super-speed-plus";
+       status = "okay";
+};
+
+&usbdrd31_phy {
        status = "okay";
 };
 
index 55e6bcb3689e93f23dc71c31f158ff9d8c203bd5..a66e996666b8785cf76c2d05ae6763eb068dd9f8 100644 (file)
                pinctrl_peric0: pinctrl@10840000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x10840000 0x00001000>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_GPIO_PERIC0_PCLK>;
+                       clock-names = "pclk";
                        interrupts = <GIC_SPI 625 IRQ_TYPE_LEVEL_HIGH 0>;
                };
 
+               usi1: usi@109000c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109000c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1000>;
+                       status = "disabled";
+
+                       hsi2c_1: i2c@10900000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10900000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c1_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_1: serial@10900000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10900000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart1_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_1: spi@10900000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10900000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_0>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_0>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi1_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi2: usi@109100c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109100c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1004>;
+                       status = "disabled";
+
+                       hsi2c_2: i2c@10910000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10910000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c2_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_2: serial@10910000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10910000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart2_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_2: spi@10910000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10910000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_1>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_1>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi2_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi3: usi@109200c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109200c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1008>;
+                       status = "disabled";
+
+                       hsi2c_3: i2c@10920000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10920000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c3_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_3: serial@10920000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10920000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart3_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_3: spi@10920000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10920000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_2>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi3_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi4: usi@109300c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109300c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x100c>;
+                       status = "disabled";
+
+                       hsi2c_4: i2c@10930000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10930000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c4_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_4: serial@10930000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10930000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart4_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_4: spi@10930000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10930000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_3>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_3>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi4_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi5: usi@109400c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109400c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1010>;
+                       status = "disabled";
+
+                       hsi2c_5: i2c@10940000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10940000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c5_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_5: serial@10940000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10940000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart5_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_5: spi@10940000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10940000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_4>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_4>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi5_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi6: usi@109500c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109500c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1014>;
+                       status = "disabled";
+
+                       hsi2c_6: i2c@10950000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10950000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c6_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_6: serial@10950000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10950000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart6_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_6: spi@10950000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10950000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_5>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_5>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi6_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi7: usi@109600c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x109600c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1018>;
+                       status = "disabled";
+
+                       hsi2c_7: i2c@10960000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10960000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c7_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_7: serial@10960000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10960000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart7_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_7: spi@10960000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10960000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_6>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_6>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi7_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
                usi8: usi@109700c0 {
-                       compatible = "google,gs101-usi",
-                                    "samsung,exynos850-usi";
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
                        reg = <0x109700c0 0x20>;
                        ranges;
                        #address-cells = <1>;
                                interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&hsi2c8_bus>;
                                clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>,
                                         <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>;
                                clock-names = "hsi2c", "hsi2c_pclk";
+                               pinctrl-0 = <&hsi2c8_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_8: serial@10970000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10970000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart8_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_8: spi@10970000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10970000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_PCLK_7>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP0_IPCLK_7>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi8_bus>;
+                               pinctrl-names = "default";
                                status = "disabled";
                        };
                };
 
                usi_uart: usi@10a000c0 {
-                       compatible = "google,gs101-usi",
-                                    "samsung,exynos850-usi";
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
                        reg = <0x10a000c0 0x20>;
                        ranges;
                        #address-cells = <1>;
                        serial_0: serial@10a00000 {
                                compatible = "google,gs101-uart";
                                reg = <0x10a00000 0xc0>;
-                               interrupts = <GIC_SPI 634
-                                             IRQ_TYPE_LEVEL_HIGH 0>;
+                               interrupts = <GIC_SPI 634 IRQ_TYPE_LEVEL_HIGH 0>;
                                clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_0>,
                                         <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_0>;
                                clock-names = "uart", "clk_uart_baud0";
+                               pinctrl-0 = <&uart0_bus>;
+                               pinctrl-names = "default";
                                samsung,uart-fifosize = <256>;
                                status = "disabled";
                        };
                };
 
+               usi14: usi@10a200c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10a200c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+                                <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric0 0x1028>;
+                       status = "disabled";
+
+                       hsi2c_14: i2c@10a20000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10a20000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c14_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_14: serial@10a20000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10a20000 0xc0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart14_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_14: spi@10a20000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10a20000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_PCLK_2>,
+                                        <&cmu_peric0 CLK_GOUT_PERIC0_PERIC0_TOP1_IPCLK_2>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi14_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
                cmu_peric1: clock-controller@10c00000 {
                        compatible = "google,gs101-cmu-peric1";
                        reg = <0x10c00000 0x4000>;
                pinctrl_peric1: pinctrl@10c40000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x10c40000 0x00001000>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_GPIO_PERIC1_PCLK>;
+                       clock-names = "pclk";
                        interrupts = <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH 0>;
                };
 
+               usi0: usi@10d100c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10d100c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+                                <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric1 0x1000>;
+                       status = "disabled";
+
+                       hsi2c_0: i2c@10d10000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10d10000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c0_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_usi0: serial@10d10000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d10000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart0_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_0: spi@10d10000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d10000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_1>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_1>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 651 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi0_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi9: usi@10d200c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10d200c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+                                <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric1 0x1004>;
+                       status = "disabled";
+
+                       hsi2c_9: i2c@10d20000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10d20000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c9_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_9: serial@10d20000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d20000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart9_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_9: spi@10d20000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d20000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_2>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_2>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 652 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi9_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi10: usi@10d300c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10d300c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+                                <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric1 0x1008>;
+                       status = "disabled";
+
+                       hsi2c_10: i2c@10d30000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10d30000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c10_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_10: serial@10d30000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d30000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart10_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_10: spi@10d30000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d30000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_3>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_3>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi10_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi11: usi@10d400c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10d400c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+                                <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric1 0x100c>;
+                       status = "disabled";
+
+                       hsi2c_11: i2c@10d40000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10d40000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c11_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_11: serial@10d40000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d40000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart11_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_11: spi@10d40000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d40000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_4>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_4>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 654 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi11_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
                usi12: usi@10d500c0 {
-                       compatible = "google,gs101-usi",
-                                    "samsung,exynos850-usi";
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
                        reg = <0x10d500c0 0x20>;
                        ranges;
                        #address-cells = <1>;
                                interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
-                               pinctrl-0 = <&hsi2c12_bus>;
-                               pinctrl-names = "default";
                                clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>,
                                         <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>;
                                clock-names = "hsi2c", "hsi2c_pclk";
+                               pinctrl-0 = <&hsi2c12_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_12: serial@10d50000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d50000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart12_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_12: spi@10d50000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d50000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_5>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_5>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 655 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi12_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               usi13: usi@10d600c0 {
+                       compatible = "google,gs101-usi", "samsung,exynos850-usi";
+                       reg = <0x10d600c0 0x20>;
+                       ranges;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+                                <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+                       clock-names = "pclk", "ipclk";
+                       samsung,sysreg = <&sysreg_peric1 0x1014>;
+                       status = "disabled";
+
+                       hsi2c_13: i2c@10d60000 {
+                               compatible = "google,gs101-hsi2c",
+                                            "samsung,exynosautov9-hsi2c";
+                               reg = <0x10d60000 0xc0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>;
+                               clock-names = "hsi2c", "hsi2c_pclk";
+                               interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&hsi2c13_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+
+                       serial_13: serial@10d60000 {
+                               compatible = "google,gs101-uart";
+                               reg = <0x10d60000 0xc0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+                               clock-names = "uart", "clk_uart_baud0";
+                               interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&uart13_bus_single>;
+                               pinctrl-names = "default";
+                               samsung,uart-fifosize = <64>;
+                               status = "disabled";
+                       };
+
+                       spi_13: spi@10d60000 {
+                               compatible = "google,gs101-spi";
+                               reg = <0x10d60000 0x30>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_PCLK_6>,
+                                        <&cmu_peric1 CLK_GOUT_PERIC1_PERIC1_TOP0_IPCLK_6>;
+                               clock-names = "spi", "spi_busclk0";
+                               interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+                               pinctrl-0 = <&spi13_bus>;
+                               pinctrl-names = "default";
+                               status = "disabled";
+                       };
+               };
+
+               cmu_hsi0: clock-controller@11000000 {
+                       compatible = "google,gs101-cmu-hsi0";
+                       reg = <0x11000000 0x4000>;
+                       #clock-cells = <1>;
+
+                       clocks = <&ext_24_5m>,
+                                <&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
+                                <&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>,
+                                <&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
+                                <&cmu_top CLK_DOUT_CMU_HSI0_USBDPDBG>;
+                       clock-names = "oscclk", "bus", "dpgtc", "usb31drd",
+                                     "usbdpdbg";
+               };
+
+               usbdrd31_phy: phy@11100000 {
+                       compatible = "google,gs101-usb31drd-phy";
+                       reg = <0x11100000 0x0100>,
+                             <0x110f0000 0x0800>,
+                             <0x110e0000 0x2800>;
+                       reg-names = "phy", "pcs", "pma";
+                       clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL>,
+                                <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB20_PHY_REFCLK_26>,
+                                <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_CTRL_ACLK>,
+                                <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_CTRL_PCLK>,
+                                <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USBDPPHY_SCL_APB_PCLK>;
+                       clock-names = "phy", "ref", "ctrl_aclk", "ctrl_pclk", "scl_pclk";
+                       samsung,pmu-syscon = <&pmu_system_controller>;
+                       #phy-cells = <1>;
+                       status = "disabled";
+               };
+
+               usbdrd31: usb@11110000 {
+                       compatible = "google,gs101-dwusb3";
+                       clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY>,
+                               <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_SUSPEND_CLK_26>,
+                               <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_LINK_ACLK>,
+                               <&cmu_hsi0 CLK_GOUT_HSI0_UASC_HSI0_LINK_PCLK>;
+                       clock-names = "bus_early", "susp_clk", "link_aclk", "link_pclk";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x11110000 0x10000>;
+                       status = "disabled";
+
+                       usbdrd31_dwc3: usb@0 {
+                               compatible = "snps,dwc3";
+                               clocks = <&cmu_hsi0 CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_REF_CLK_40>;
+                               clock-names = "ref";
+                               reg = <0x0 0x10000>;
+                               interrupts = <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH 0>;
+                               phys = <&usbdrd31_phy 0>, <&usbdrd31_phy 1>;
+                               phy-names = "usb2-phy", "usb3-phy";
                                status = "disabled";
                        };
                };
                pinctrl_hsi1: pinctrl@11840000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x11840000 0x00001000>;
+                       /* TODO: update once support for this CMU exists */
+                       clocks = <0>;
+                       clock-names = "pclk";
                        interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH 0>;
                };
 
+               cmu_hsi2: clock-controller@14400000 {
+                       compatible = "google,gs101-cmu-hsi2";
+                       reg = <0x14400000 0x4000>;
+                       #clock-cells = <1>;
+                       clocks = <&ext_24_5m>,
+                                <&cmu_top CLK_DOUT_CMU_HSI2_BUS>,
+                                <&cmu_top CLK_DOUT_CMU_HSI2_PCIE>,
+                                <&cmu_top CLK_DOUT_CMU_HSI2_UFS_EMBD>,
+                                <&cmu_top CLK_DOUT_CMU_HSI2_MMC_CARD>;
+                       clock-names = "oscclk", "bus", "pcie", "ufs", "mmc";
+               };
+
+               sysreg_hsi2: syscon@14420000 {
+                       compatible = "google,gs101-hsi2-sysreg", "syscon";
+                       reg = <0x14420000 0x10000>;
+                       clocks = <&cmu_hsi2 CLK_GOUT_HSI2_SYSREG_HSI2_PCLK>;
+               };
+
                pinctrl_hsi2: pinctrl@14440000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x14440000 0x00001000>;
+                       clocks = <&cmu_hsi2 CLK_GOUT_HSI2_GPIO_HSI2_PCLK>;
+                       clock-names = "pclk";
                        interrupts = <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>;
                };
 
+               ufs_0: ufs@14700000 {
+                       compatible = "google,gs101-ufs";
+                       reg = <0x14700000 0x200>,
+                             <0x14701100 0x200>,
+                             <0x14780000 0xa000>,
+                             <0x14600000 0x100>;
+                       reg-names = "hci", "vs_hci", "unipro", "ufsp";
+                       interrupts = <GIC_SPI 532 IRQ_TYPE_LEVEL_HIGH 0>;
+                       clocks = <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_ACLK>,
+                                <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_CLK_UNIPRO>,
+                                <&cmu_hsi2 CLK_GOUT_HSI2_UFS_EMBD_I_FMP_CLK>,
+                                <&cmu_hsi2 CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_ACLK>,
+                                <&cmu_hsi2 CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_PCLK>,
+                                <&cmu_hsi2 CLK_GOUT_HSI2_SYSREG_HSI2_PCLK>;
+                       clock-names = "core_clk", "sclk_unipro_main", "fmp",
+                                     "aclk", "pclk", "sysreg";
+                       freq-table-hz = <0 0>, <0 0>, <0 0>, <0 0>, <0 0>, <0 0>;
+                       pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>;
+                       pinctrl-names = "default";
+                       phys = <&ufs_0_phy>;
+                       phy-names = "ufs-phy";
+                       samsung,sysreg = <&sysreg_hsi2 0x710>;
+                       status = "disabled";
+               };
+
+               ufs_0_phy: phy@14704000 {
+                       compatible = "google,gs101-ufs-phy";
+                       reg = <0x14704000 0x3000>;
+                       reg-names = "phy-pma";
+                       samsung,pmu-syscon = <&pmu_system_controller>;
+                       #phy-cells = <0>;
+                       clocks = <&ext_24_5m>;
+                       clock-names = "ref_clk";
+                       status = "disabled";
+               };
+
                cmu_apm: clock-controller@17400000 {
                        compatible = "google,gs101-cmu-apm";
                        reg = <0x17400000 0x8000>;
                pinctrl_gpio_alive: pinctrl@174d0000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x174d0000 0x00001000>;
+                       clocks = <&cmu_apm CLK_GOUT_APM_APBIF_GPIO_ALIVE_PCLK>;
+                       clock-names = "pclk";
 
                        wakeup-interrupt-controller {
                                compatible = "google,gs101-wakeup-eint",
                pinctrl_far_alive: pinctrl@174e0000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x174e0000 0x00001000>;
+                       clocks = <&cmu_apm CLK_GOUT_APM_APBIF_GPIO_FAR_ALIVE_PCLK>;
+                       clock-names = "pclk";
 
                        wakeup-interrupt-controller {
                                compatible = "google,gs101-wakeup-eint",
                pinctrl_gsactrl: pinctrl@17940000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x17940000 0x00001000>;
+                       /* TODO: update once support for this CMU exists */
+                       clocks = <0>;
+                       clock-names = "pclk";
                };
 
                pinctrl_gsacore: pinctrl@17a80000 {
                        compatible = "google,gs101-pinctrl";
                        reg = <0x17a80000 0x00001000>;
+                       /* TODO: update once support for this CMU exists */
+                       clocks = <0>;
+                       clock-names = "pclk";
                };
 
                cmu_top: clock-controller@1e080000 {
index 045250d0a04046eb8e214278f799ce2fc1c706f3..bd443c2bc5a48c7aad08f5020c96cefa8b5caaed 100644 (file)
@@ -9,6 +9,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-kbox-a-230-ls.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var1.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
@@ -98,6 +99,10 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-11-x.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-8-x.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-tqmlx2160a-mblx2160a-14-7-x.dtb
 
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-aster.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-eval-v3.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-iris-v2.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8dx-colibri-iris.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
@@ -166,6 +171,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-dhcom-pdk3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-icore-mx8mp-edimm2.2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-msc-sm2s-ep1.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mp-navqp.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-hdmi.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mp-skov-revb-lt6.dtb
@@ -259,4 +265,5 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-venice-gw74xx-rpidsi.dtb
 
 dtb-$(CONFIG_ARCH_S32) += s32g274a-evb.dtb
 dtb-$(CONFIG_ARCH_S32) += s32g274a-rdb2.dtb
+dtb-$(CONFIG_ARCH_S32) += s32g399a-rdb3.dtb
 dtb-$(CONFIG_ARCH_S32) += s32v234-evb.dtb
index fe9093b3c02e2cdee19e8637b859d57122da1b65..a0f7bbd691a0047f5810aff4a34958cdc5dc75cf 100644 (file)
@@ -81,7 +81,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index ed4e69e87e30b14f87c0652f874feb6286cadd77..195bdbafdf7c9e0cf7dbcccfd75a6ec17ac56a2f 100644 (file)
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include <dt-bindings/clock/fsl,qoriq-clockgen.h>
-#include "fsl-ls1028a-kontron-sl28.dts"
+#include "fsl-ls1028a-kontron-sl28-var3.dts"
 
 / {
        model = "Kontron SMARC-sAL28 (Single PHY) on SMARC Eval 2.0 carrier";
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var3.dts
new file mode 100644 (file)
index 0000000..08851ca
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Device Tree file for the Kontron SMARC-sAL28 board.
+ *
+ * This is for the network variant 3 which has one ethernet ports.
+ *
+ * Copyright (C) 2024 Michael Walle <michael@walle.cc>
+ *
+ */
+
+/dts-v1/;
+
+#include "fsl-ls1028a-kontron-sl28.dts"
+
+/ {
+       model = "Kontron SMARC-sAL28 (Single PHY)";
+       compatible = "kontron,sl28-var3", "kontron,sl28", "fsl,ls1028a";
+};
index ae534c23b970a2f58558bee9e1ec0940579adf02..70b8731029c4e2cfe5736578cec2cf855125a8e9 100644 (file)
                                  0xc2000000 0x1 0xf8230000  0x1 0xf8230000  0x0 0x020000
                                  /* BAR4 (PF5) - non-prefetchable memory */
                                  0x82000000 0x1 0xfc000000  0x1 0xfc000000  0x0 0x400000>;
+                       #interrupt-cells = <1>;
+                       interrupt-map-mask = <0 0 0 7>;
+                       interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0000 0 0 2 &gic 0 0 GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
 
                        enetc_port0: ethernet@0,0 {
-                               compatible = "fsl,enetc";
+                               compatible = "pci1957,e100", "fsl,enetc";
                                reg = <0x000000 0 0 0 0>;
                                status = "disabled";
                        };
 
                        enetc_port1: ethernet@0,1 {
-                               compatible = "fsl,enetc";
+                               compatible = "pci1957,e100", "fsl,enetc";
                                reg = <0x000100 0 0 0 0>;
                                status = "disabled";
                        };
 
                        enetc_port2: ethernet@0,2 {
-                               compatible = "fsl,enetc";
+                               compatible = "pci1957,e100", "fsl,enetc";
                                reg = <0x000200 0 0 0 0>;
                                phy-mode = "internal";
                                status = "disabled";
                        };
 
                        enetc_mdio_pf3: mdio@0,3 {
-                               compatible = "fsl,enetc-mdio";
+                               compatible = "pci1957,ee01", "fsl,enetc-mdio";
                                reg = <0x000300 0 0 0 0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                        };
 
                        ethernet@0,4 {
-                               compatible = "fsl,enetc-ptp";
+                               compatible = "pci1957,ee02", "fsl,enetc-ptp";
                                reg = <0x000400 0 0 0 0>;
                                clocks = <&clockgen QORIQ_CLK_HWACCEL 3>;
                                little-endian;
                        mscc_felix: ethernet-switch@0,5 {
                                reg = <0x000500 0 0 0 0>;
                                /* IEP INT_B */
-                               interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <2>;
                                status = "disabled";
 
                                mscc_felix_ports: ports {
                        };
 
                        enetc_port3: ethernet@0,6 {
-                               compatible = "fsl,enetc";
+                               compatible = "pci1957,e100", "fsl,enetc";
                                reg = <0x000600 0 0 0 0>;
                                phy-mode = "internal";
                                status = "disabled";
                        rcec@1f,0 {
                                reg = <0x00f800 0 0 0 0>;
                                /* IEP INT_A */
-                               interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <1>;
                        };
                };
 
index d333b773bc455e5f2a5e370398fd458155965e23..8ee6d8c0ef6194fb8ba4e1155818e0dc43338722 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <0 106 0x4>,
                             <0 107 0x4>,
                             <0 95 0x4>,
index 1aa38ed09aa4fa89c29f651d175e75c78593e079..8352197cea6f426fda2e8537f40965c567171306 100644 (file)
 #include <dt-bindings/clock/fsl,qoriq-clockgen.h>
 #include "fsl-ls208xa.dtsi"
 
+/ {
+       pmu {
+               compatible = "arm,cortex-a57-pmu";
+               interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
+       };
+};
+
 &cpu {
        cpu0: cpu@0 {
                device_type = "cpu";
index 8581ea55d2540f087e5944beafde9a16f1637db4..245bbd615c81c14d8f83baaece9740191671da63 100644 (file)
 #include <dt-bindings/clock/fsl,qoriq-clockgen.h>
 #include "fsl-ls208xa.dtsi"
 
+/ {
+       pmu {
+               compatible = "arm,cortex-a72-pmu";
+               interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
+       };
+};
+
 &cpu {
        cpu0: cpu@0 {
                device_type = "cpu";
index 0b72928359068057e4faddaab4628a9e6b5f8efd..ccba0a135b247e8c2f96e12c319c61c3d4efbd08 100644 (file)
                             <1 10 4>; /* Hypervisor PPI, active-low */
        };
 
-       pmu {
-               compatible = "arm,armv8-pmuv3";
-               interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
-       };
-
        psci {
                compatible = "arm,psci-0.2";
                method = "smc";
index e665c629e1a1f6f6bf6d38e4711f3ad47c1da0dd..96055593204ab8b5f21b039dd69fb50cb6f7d91f 100644 (file)
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
-                       scl-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c0_scl>;
+                       pinctrl-1 = <&i2c0_scl_gpio>;
+                       scl-gpios = <&gpio0 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c1_scl>;
+                       pinctrl-1 = <&i2c1_scl_gpio>;
+                       scl-gpios = <&gpio0 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c2_scl>;
+                       pinctrl-1 = <&i2c2_scl_gpio>;
+                       scl-gpios = <&gpio0 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c3_scl>;
+                       pinctrl-1 = <&i2c3_scl_gpio>;
+                       scl-gpios = <&gpio0 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
-                       scl-gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c4_scl>;
+                       pinctrl-1 = <&i2c4_scl_gpio>;
+                       scl-gpios = <&gpio0 25 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c5_scl>;
+                       pinctrl-1 = <&i2c5_scl_gpio>;
+                       scl-gpios = <&gpio0 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c6_scl>;
+                       pinctrl-1 = <&i2c6_scl_gpio>;
+                       scl-gpios = <&gpio1 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        clock-names = "i2c";
                        clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL
                                            QORIQ_CLK_PLL_DIV(16)>;
+                       pinctrl-names = "default", "gpio";
+                       pinctrl-0 = <&i2c7_scl>;
+                       pinctrl-1 = <&i2c7_scl_gpio>;
+                       scl-gpios = <&gpio1 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
                        status = "disabled";
                };
 
                        };
                };
 
+               pinmux_i2crv: pinmux@70010012c {
+                       compatible = "pinctrl-single";
+                       reg = <0x00000007 0x0010012c 0x0 0xc>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       pinctrl-single,bit-per-mux;
+                       pinctrl-single,register-width = <32>;
+                       pinctrl-single,function-mask = <0x7>;
+
+                       i2c1_scl: i2c1-scl-pins {
+                               pinctrl-single,bits = <0x0 0 0x7>;
+                       };
+
+                       i2c1_scl_gpio: i2c1-scl-gpio-pins {
+                               pinctrl-single,bits = <0x0 0x1 0x7>;
+                       };
+
+                       i2c2_scl: i2c2-scl-pins {
+                               pinctrl-single,bits = <0x0 0 (0x7 << 3)>;
+                       };
+
+                       i2c2_scl_gpio: i2c2-scl-gpio-pins {
+                               pinctrl-single,bits = <0x0 (0x1 << 3) (0x7 << 3)>;
+                       };
+
+                       i2c3_scl: i2c3-scl-pins {
+                               pinctrl-single,bits = <0x0 0 (0x7 << 6)>;
+                       };
+
+                       i2c3_scl_gpio: i2c3-scl-gpio-pins {
+                               pinctrl-single,bits = <0x0 (0x1 << 6) (0x7 << 6)>;
+                       };
+
+                       i2c4_scl: i2c4-scl-pins {
+                               pinctrl-single,bits = <0x0 0 (0x7 << 9)>;
+                       };
+
+                       i2c4_scl_gpio: i2c4-scl-gpio-pins {
+                               pinctrl-single,bits = <0x0 (0x1 << 9) (0x7 << 9)>;
+                       };
+
+                       i2c5_scl: i2c5-scl-pins {
+                               pinctrl-single,bits = <0x0 0 (0x7 << 12)>;
+                       };
+
+                       i2c5_scl_gpio: i2c5-scl-gpio-pins {
+                               pinctrl-single,bits = <0x0 (0x1 << 12) (0x7 << 12)>;
+                       };
+
+                       i2c6_scl: i2c6-scl-pins {
+                               pinctrl-single,bits = <0x4 0x2 0x7>;
+                       };
+
+                       i2c6_scl_gpio: i2c6-scl-gpio-pins {
+                               pinctrl-single,bits = <0x4 0x1 0x7>;
+                       };
+
+                       i2c7_scl: i2c7-scl-pins {
+                               pinctrl-single,bits = <0x4 0x2 0x7>;
+                       };
+
+                       i2c7_scl_gpio: i2c7-scl-gpio-pins {
+                               pinctrl-single,bits = <0x4 0x1 0x7>;
+                       };
+
+                       i2c0_scl: i2c0-scl-pins {
+                               pinctrl-single,bits = <0x8 0 (0x7 << 10)>;
+                       };
+
+                       i2c0_scl_gpio: i2c0-scl-gpio-pins {
+                               pinctrl-single,bits = <0x8 (0x1 << 10) (0x7 << 10)>;
+                       };
+               };
+
                fsl_mc: fsl-mc@80c000000 {
                        compatible = "fsl,qoriq-mc";
                        reg = <0x00000008 0x0c000000 0 0x40>,
index 9f88583aa25ea7c07ae9f6ca7f11fe5a7904acc2..eafef8718a0fe6d1043530040d1fab29733ca897 100644 (file)
@@ -25,6 +25,7 @@
                i2c7 = &mpcie1_i2c;
                i2c8 = &mpcie0_i2c;
                i2c9 = &pcieclk_i2c;
+               i2c10 = &i2c5;
                mmc0 = &esdhc0;
                mmc1 = &esdhc1;
                serial0 = &uart0;
index 0580ea30cfbc8d78a0e85adf63bf31130f61ab27..e914291e63a1ae46c01bc6c3c701a8d7ed11a7ff 100644 (file)
                reg = <0x54>;
        };
 };
+
+&i2c5 {
+       status = "okay";
+
+       rtc@6f {
+               compatible = "microchip,mcp7940x";
+               reg = <0x6f>;
+       };
+};
index 07afeb78ed56483e8784f26add43f73c6b58c811..897cbb7b6742205b296ee4d5e0986474ed9bfe82 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <dt-bindings/clock/imx8-clock.h>
 #include <dt-bindings/clock/imx8-lpcg.h>
+#include <dt-bindings/dma/fsl-edma.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 
 audio_ipg_clk: clock-audio-ipg {
@@ -119,13 +120,96 @@ audio_subsys: bus@59000000 {
        #size-cells = <1>;
        ranges = <0x59000000 0x0 0x59000000 0x1000000>;
 
+       asrc0: asrc@59000000 {
+               compatible = "fsl,imx8qm-asrc";
+               reg = <0x59000000 0x10000>;
+               interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&asrc0_lpcg IMX_LPCG_CLK_0>,
+                        <&asrc0_lpcg IMX_LPCG_CLK_0>,
+                        <&aud_pll_div0_lpcg IMX_LPCG_CLK_4>,
+                        <&aud_pll_div1_lpcg IMX_LPCG_CLK_4>,
+                        <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+                        <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>;
+               clock-names = "mem", "ipg",
+                             "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+                             "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+                             "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+                             "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+                             "spba";
+               dmas = <&edma0 0 0 0>,
+                      <&edma0 1 0 0>,
+                      <&edma0 2 0 0>,
+                      <&edma0 3 0 FSL_EDMA_RX>,
+                      <&edma0 4 0 FSL_EDMA_RX>,
+                      <&edma0 5 0 FSL_EDMA_RX>;
+               /* tx* is output channel of asrc, it is rx channel for eDMA */
+               dma-names = "rxa", "rxb", "rxc", "txa", "txb", "txc";
+               fsl,asrc-rate = <8000>;
+               fsl,asrc-width = <16>;
+               fsl,asrc-clk-map = <0>;
+               power-domains = <&pd IMX_SC_R_ASRC_0>;
+               status = "disabled";
+       };
+
+       esai0: esai@59010000 {
+               compatible = "fsl,imx8qm-esai";
+               reg = <0x59010000 0x10000>;
+               interrupts = <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&esai0_lpcg IMX_LPCG_CLK_4>,
+                        <&esai0_lpcg IMX_LPCG_CLK_0>,
+                        <&esai0_lpcg IMX_LPCG_CLK_4>,
+                        <&clk_dummy>;
+               clock-names = "core", "extal", "fsys", "spba";
+               dmas = <&edma0 6 0 FSL_EDMA_RX>, <&edma0 7 0 0>;
+               dma-names = "rx", "tx";
+               power-domains = <&pd IMX_SC_R_ESAI_0>;
+               status = "disabled";
+       };
+
+       spdif0: spdif@59020000 {
+               compatible = "fsl,imx8qm-spdif";
+               reg = <0x59020000 0x10000>;
+               interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, /* rx */
+                            <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>; /* tx */
+               clocks = <&spdif0_lpcg IMX_LPCG_CLK_4>, /* core */
+                        <&clk_dummy>,                  /* rxtx0 */
+                        <&spdif0_lpcg IMX_LPCG_CLK_0>, /* rxtx1 */
+                        <&clk_dummy>,                  /* rxtx2 */
+                        <&clk_dummy>,                  /* rxtx3 */
+                        <&clk_dummy>,                  /* rxtx4 */
+                        <&audio_ipg_clk>,              /* rxtx5 */
+                        <&clk_dummy>,                  /* rxtx6 */
+                        <&clk_dummy>,                  /* rxtx7 */
+                        <&clk_dummy>;                  /* spba */
+               clock-names = "core", "rxtx0", "rxtx1", "rxtx2", "rxtx3", "rxtx4",
+                             "rxtx5", "rxtx6", "rxtx7", "spba";
+               dmas = <&edma0 8 0 (FSL_EDMA_MULTI_FIFO | FSL_EDMA_RX)>,
+                      <&edma0 9 0 FSL_EDMA_MULTI_FIFO>;
+               dma-names = "rx", "tx";
+               power-domains = <&pd IMX_SC_R_SPDIF_0>;
+               status = "disabled";
+       };
+
        sai0: sai@59040000 {
                compatible = "fsl,imx8qm-sai";
                reg = <0x59040000 0x10000>;
                interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sai0_lpcg 1>,
+               clocks = <&sai0_lpcg IMX_LPCG_CLK_4>,
                         <&clk_dummy>,
-                        <&sai0_lpcg 0>,
+                        <&sai0_lpcg IMX_LPCG_CLK_0>,
                         <&clk_dummy>,
                         <&clk_dummy>;
                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -139,9 +223,9 @@ audio_subsys: bus@59000000 {
                compatible = "fsl,imx8qm-sai";
                reg = <0x59050000 0x10000>;
                interrupts = <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sai1_lpcg 1>,
+               clocks = <&sai1_lpcg IMX_LPCG_CLK_4>,
                         <&clk_dummy>,
-                        <&sai1_lpcg 0>,
+                        <&sai1_lpcg IMX_LPCG_CLK_0>,
                         <&clk_dummy>,
                         <&clk_dummy>;
                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -155,9 +239,9 @@ audio_subsys: bus@59000000 {
                compatible = "fsl,imx8qm-sai";
                reg = <0x59060000 0x10000>;
                interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sai2_lpcg 1>,
+               clocks = <&sai2_lpcg IMX_LPCG_CLK_4>,
                         <&clk_dummy>,
-                        <&sai2_lpcg 0>,
+                        <&sai2_lpcg IMX_LPCG_CLK_0>,
                         <&clk_dummy>,
                         <&clk_dummy>;
                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -171,9 +255,9 @@ audio_subsys: bus@59000000 {
                compatible = "fsl,imx8qm-sai";
                reg = <0x59070000 0x10000>;
                interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&sai3_lpcg 1>,
+               clocks = <&sai3_lpcg IMX_LPCG_CLK_4>,
                         <&clk_dummy>,
-                        <&sai3_lpcg 0>,
+                        <&sai3_lpcg IMX_LPCG_CLK_0>,
                         <&clk_dummy>,
                         <&clk_dummy>;
                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
@@ -239,6 +323,40 @@ audio_subsys: bus@59000000 {
                                <&pd IMX_SC_R_DMA_0_CH23>;
        };
 
+       asrc0_lpcg: clock-controller@59400000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59400000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_4>;
+               clock-output-names = "asrc0_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_ASRC_0>;
+       };
+
+       esai0_lpcg: clock-controller@59410000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59410000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&acm IMX_ADMA_ACM_ESAI0_MCLK_SEL>,
+                        <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "esai0_lpcg_extal_clk",
+                                    "esai0_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_ESAI_0>;
+       };
+
+       spdif0_lpcg: clock-controller@59420000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59420000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&acm IMX_ADMA_ACM_SPDIF0_TX_CLK_SEL>,
+                        <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "spdif0_lpcg_tx_clk",
+                                    "spdif0_lpcg_gclkw";
+               power-domains = <&pd IMX_SC_R_SPDIF_0>;
+       };
+
        sai0_lpcg: clock-controller@59440000 {
                compatible = "fsl,imx8qxp-lpcg";
                reg = <0x59440000 0x10000>;
@@ -333,6 +451,101 @@ audio_subsys: bus@59000000 {
                status = "disabled";
        };
 
+       asrc1: asrc@59800000 {
+               compatible = "fsl,imx8qm-asrc";
+               reg = <0x59800000 0x10000>;
+               interrupts = <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&asrc1_lpcg IMX_LPCG_CLK_4>,
+                        <&asrc1_lpcg IMX_LPCG_CLK_4>,
+                        <&aud_pll_div0_lpcg IMX_LPCG_CLK_0>,
+                        <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>,
+                        <&acm IMX_ADMA_ACM_AUD_CLK0_SEL>,
+                        <&acm IMX_ADMA_ACM_AUD_CLK1_SEL>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>,
+                        <&clk_dummy>;
+               clock-names = "mem", "ipg",
+                             "asrck_0", "asrck_1", "asrck_2", "asrck_3",
+                             "asrck_4", "asrck_5", "asrck_6", "asrck_7",
+                             "asrck_8", "asrck_9", "asrck_a", "asrck_b",
+                             "asrck_c", "asrck_d", "asrck_e", "asrck_f",
+                             "spba";
+               dmas = <&edma1 0 0 0>,
+                      <&edma1 1 0 0>,
+                      <&edma1 2 0 0>,
+                      <&edma1 3 0 FSL_EDMA_RX>,
+                      <&edma1 4 0 FSL_EDMA_RX>,
+                      <&edma1 5 0 FSL_EDMA_RX>;
+               /* tx* is output channel of asrc, it is rx channel for eDMA */
+               dma-names = "rxa", "rxb", "rxc", "txa", "txb", "txc";
+               fsl,asrc-rate = <8000>;
+               fsl,asrc-width = <16>;
+               fsl,asrc-clk-map = <1>;
+               power-domains = <&pd IMX_SC_R_ASRC_1>;
+               status = "disabled";
+       };
+
+       sai4: sai@59820000 {
+               compatible = "fsl,imx8qm-sai";
+               reg = <0x59820000 0x10000>;
+               interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sai4_lpcg IMX_LPCG_CLK_4>,
+                        <&clk_dummy>,
+                        <&sai4_lpcg IMX_LPCG_CLK_0>,
+                        <&clk_dummy>,
+                        <&clk_dummy>;
+               clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+               dmas = <&edma1 8 0 FSL_EDMA_RX>, <&edma1 9 0 0>;
+               dma-names = "rx", "tx";
+               power-domains = <&pd IMX_SC_R_SAI_4>;
+               status = "disabled";
+       };
+
+       sai5: sai@59830000 {
+               compatible = "fsl,imx8qm-sai";
+               reg = <0x59830000 0x10000>;
+               interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&sai5_lpcg IMX_LPCG_CLK_4>,
+                        <&clk_dummy>,
+                        <&sai5_lpcg IMX_LPCG_CLK_0>,
+                        <&clk_dummy>,
+                        <&clk_dummy>;
+               clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
+               dmas = <&edma1 10 0 0>;
+               dma-names = "tx";
+               power-domains = <&pd IMX_SC_R_SAI_5>;
+               status = "disabled";
+       };
+
+       amix: amix@59840000 {
+               compatible = "fsl,imx8qm-audmix";
+               reg = <0x59840000 0x10000>;
+               clocks = <&amix_lpcg IMX_LPCG_CLK_0>;
+               clock-names = "ipg";
+               power-domains = <&pd IMX_SC_R_AMIX>;
+               dais = <&sai4>, <&sai5>;
+               status = "disabled";
+       };
+
+       mqs: mqs@59850000 {
+               compatible = "fsl,imx8qm-mqs";
+               reg = <0x59850000 0x10000>;
+               clocks = <&mqs0_lpcg IMX_LPCG_CLK_4>, <&mqs0_lpcg IMX_LPCG_CLK_0>;
+               clock-names = "mclk", "core";
+               power-domains = <&pd IMX_SC_R_MQS_0>;
+               status = "disabled";
+       };
+
        edma1: dma-controller@599f0000 {
                compatible = "fsl,imx8qm-edma";
                reg = <0x599f0000 0xc0000>;
@@ -481,4 +694,60 @@ audio_subsys: bus@59000000 {
                              "sai3_rx_bclk",
                              "sai4_rx_bclk";
        };
+
+       asrc1_lpcg: clock-controller@59c00000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59c00000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_4>;
+               clock-output-names = "asrc1_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_ASRC_1>;
+       };
+
+       sai4_lpcg: clock-controller@59c20000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59c20000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&acm IMX_ADMA_ACM_SAI4_MCLK_SEL>,
+                        <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "sai4_lpcg_mclk",
+                                    "sai4_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_SAI_4>;
+       };
+
+       sai5_lpcg: clock-controller@59c30000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59c30000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&acm IMX_ADMA_ACM_SAI5_MCLK_SEL>,
+                        <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "sai5_lpcg_mclk",
+                                    "sai5_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_SAI_5>;
+       };
+
+       amix_lpcg: clock-controller@59c40000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59c40000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>;
+               clock-output-names = "amix_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_AMIX>;
+       };
+
+       mqs0_lpcg: clock-controller@59c50000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x59c50000 0x10000>;
+               #clock-cells = <1>;
+               clocks = <&acm IMX_ADMA_ACM_MQS_TX_CLK_SEL>,
+                        <&audio_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "mqs0_lpcg_mclk",
+                                    "mqs0_lpcg_ipg_clk";
+               power-domains = <&pd IMX_SC_R_MQS_0>;
+       };
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-cm40.dtsi
new file mode 100644 (file)
index 0000000..92752c0
--- /dev/null
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 NXP
+ *     Dong Aisheng <aisheng.dong@nxp.com>
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+
+cm40_ipg_clk: clock-cm40-ipg {
+       compatible = "fixed-clock";
+       #clock-cells = <0>;
+       clock-frequency = <132000000>;
+       clock-output-names = "cm40_ipg_clk";
+};
+
+cm40_subsys: bus@34000000 {
+       compatible = "simple-bus";
+       #address-cells = <1>;
+       #size-cells = <1>;
+       ranges = <0x34000000 0x0 0x34000000 0x4000000>;
+       interrupt-parent = <&cm40_intmux>;
+
+       cm40_lpuart: serial@37220000 {
+               compatible = "fsl,imx8qxp-lpuart";
+               reg = <0x37220000 0x1000>;
+               interrupts = <7 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cm40_uart_lpcg IMX_LPCG_CLK_1>, <&cm40_uart_lpcg IMX_LPCG_CLK_0>;
+               clock-names = "ipg", "baud";
+               assigned-clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <24000000>;
+               power-domains = <&pd IMX_SC_R_M4_0_UART>;
+               status = "disabled";
+       };
+
+       cm40_i2c: i2c@37230000 {
+               compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
+               reg = <0x37230000 0x1000>;
+               interrupts = <9 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cm40_i2c_lpcg IMX_LPCG_CLK_0>,
+                        <&cm40_i2c_lpcg IMX_LPCG_CLK_4>;
+               clock-names = "per", "ipg";
+               assigned-clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>;
+               assigned-clock-rates = <24000000>;
+               power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+               status = "disabled";
+       };
+
+       cm40_intmux: intmux@37400000 {
+               compatible = "fsl,imx-intmux";
+               reg = <0x37400000 0x1000>;
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                            <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>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               clocks = <&cm40_ipg_clk>;
+               clock-names = "ipg";
+               power-domains = <&pd IMX_SC_R_M4_0_INTMUX>;
+               status = "disabled";
+       };
+
+       cm40_uart_lpcg: clock-controller@37620000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x37620000 0x1000>;
+               #clock-cells = <1>;
+               clocks = <&clk IMX_SC_R_M4_0_UART IMX_SC_PM_CLK_PER>,
+                        <&cm40_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>;
+               clock-output-names = "cm40_lpcg_uart_clk",
+                                    "cm40_lpcg_uart_ipg_clk";
+               power-domains = <&pd IMX_SC_R_M4_0_UART>;
+       };
+
+       cm40_i2c_lpcg: clock-controller@37630000 {
+               compatible = "fsl,imx8qxp-lpcg";
+               reg = <0x37630000 0x1000>;
+               #clock-cells = <1>;
+               clocks = <&clk IMX_SC_R_M4_0_I2C IMX_SC_PM_CLK_PER>,
+                        <&cm40_ipg_clk>;
+               clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_4>;
+               clock-output-names = "cm40_lpcg_i2c_clk",
+                                    "cm40_lpcg_i2c_ipg_clk";
+               power-domains = <&pd IMX_SC_R_M4_0_I2C>;
+       };
+};
index e7783cc2d8303360fdd493cf58ed94c10abb87db..77d2928997b4be51a08ab2f0919dd707c21a5274 100644 (file)
@@ -21,7 +21,6 @@ img_subsys: bus@58000000 {
                interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
                         <&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
-               clock-names = "per", "ipg";
                assigned-clocks = <&img_jpeg_dec_lpcg IMX_LPCG_CLK_0>,
                                  <&img_jpeg_dec_lpcg IMX_LPCG_CLK_4>;
                assigned-clock-rates = <200000000>, <200000000>;
@@ -35,7 +34,6 @@ img_subsys: bus@58000000 {
                interrupts = <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
                         <&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
-               clock-names = "per", "ipg";
                assigned-clocks = <&img_jpeg_enc_lpcg IMX_LPCG_CLK_0>,
                                  <&img_jpeg_enc_lpcg IMX_LPCG_CLK_4>;
                assigned-clock-rates = <200000000>, <200000000>;
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-aster.dts
new file mode 100644 (file)
index 0000000..c974f5d
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-aster.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8DX on Aster Board";
+       compatible = "toradex,colibri-imx8x-aster",
+                    "toradex,colibri-imx8x",
+                    "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-eval-v3.dts
new file mode 100644 (file)
index 0000000..f2bf154
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-eval-v3.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8DX on Colibri Evaluation Board V3";
+       compatible = "toradex,colibri-imx8x-eval-v3",
+                    "toradex,colibri-imx8x",
+                    "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris-v2.dts
new file mode 100644 (file)
index 0000000..fd425c7
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris-v2.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8DX on Colibri Iris V2 Board";
+       compatible = "toradex,colibri-imx8x-iris-v2",
+                    "toradex,colibri-imx8x",
+                    "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts b/arch/arm64/boot/dts/freescale/imx8dx-colibri-iris.dts
new file mode 100644 (file)
index 0000000..e5e2346
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8dx-colibri.dtsi"
+#include "imx8x-colibri-iris.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8DX on Colibri Iris Board";
+       compatible = "toradex,colibri-imx8x-iris",
+                    "toradex,colibri-imx8x",
+                    "fsl,imx8dx";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi b/arch/arm64/boot/dts/freescale/imx8dx-colibri.dtsi
new file mode 100644 (file)
index 0000000..66b0fcc
--- /dev/null
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2018-2021 Toradex
+ */
+
+#include "imx8dx.dtsi"
+#include "imx8x-colibri.dtsi"
+
+/ {
+       model = "Toradex Colibri iMX8DX Module";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dx.dtsi b/arch/arm64/boot/dts/freescale/imx8dx.dtsi
new file mode 100644 (file)
index 0000000..ce76efc
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2020 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8dxp.dtsi"
+
+&gpu_3d0 {
+       assigned-clock-rates = <372000000>, <372000000>;
+};
index 2123d431e061374fa7ee154c279b101b5c404433..2412ab145c0661300ecf57a725e1881d5556061d 100644 (file)
@@ -16,6 +16,8 @@
                mmc0 = &usdhc1;
                mmc1 = &usdhc2;
                serial0 = &lpuart0;
+               serial1 = &lpuart1;
+               serial6 = &cm40_lpuart;
        };
 
        chosen {
                };
        };
 
+       m2_uart1_sel: regulator-m2uart1sel {
+               compatible = "regulator-fixed";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-name = "m2_uart1_sel";
+               gpio = <&pca6416_1 6 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-always-on;
+       };
+
        mux3_en: regulator-0 {
                compatible = "regulator-fixed";
                regulator-min-microvolt = <3300000>;
        status = "okay";
 };
 
+&lpuart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart1>;
+       status = "okay";
+};
+
 &flexcan2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_flexcan2>;
        status = "okay";
 };
 
+&cm40_intmux {
+       status = "disabled";
+};
+
+&cm40_lpuart {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_cm40_lpuart>;
+       status = "disabled";
+};
+
 &lsio_gpio4 {
        status = "okay";
 };
                >;
        };
 
+       pinctrl_lpuart1: lpuart1grp {
+               fsl,pins = <
+                       IMX8DXL_UART1_TX_ADMA_UART1_TX          0x06000020
+                       IMX8DXL_UART1_RX_ADMA_UART1_RX          0x06000020
+                       IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B    0x06000020
+                       IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B    0x06000020
+               >;
+       };
+
        pinctrl_usdhc1: usdhc1grp {
                fsl,pins = <
                        IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK        0x06000041
index a0674c5c55766dd3971ceea33d2514a72d13c169..7e54cf2028580832652d3a11fc37400dc4530232 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <dt-bindings/clock/imx8-clock.h>
 #include <dt-bindings/dma/fsl-edma.h>
+#include <dt-bindings/clock/imx8-lpcg.h>
 #include <dt-bindings/firmware/imx/rsrc.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a35-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
        };
 
        /* sorted in register address */
+       #include "imx8-ss-cm40.dtsi"
        #include "imx8-ss-adma.dtsi"
        #include "imx8-ss-conn.dtsi"
        #include "imx8-ss-ddr.dtsi"
 #include "imx8dxl-ss-conn.dtsi"
 #include "imx8dxl-ss-lsio.dtsi"
 #include "imx8dxl-ss-ddr.dtsi"
+
+&cm40_intmux {
+       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                    <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>;
+};
index bd5b365867fda26d130462cccdf9fda8ee2b6293..90d1901df2b1d1f80c400bb3e7d974fc61b42ed2 100644 (file)
                enable-active-high;
        };
 
+       reg_1v5: regulator-1v5 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_1V5";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+       };
+
+       reg_1v8: regulator-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
        reg_vddext_3v3: regulator-vddext-3v3 {
                compatible = "regulator-fixed";
                regulator-name = "VDDEXT_3V3";
        };
 
        ptn5110: tcpc@50 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec1>;
                reg = <0x50>;
                assigned-clock-rates = <24000000>;
                powerdown-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+               DOVDD-supply = <&buck5_reg>;
+               AVDD-supply = <&reg_1v8>;
+               DVDD-supply = <&reg_1v5>;
 
                port {
                        ov5640_to_mipi_csi2: endpoint {
index d643381417f1cac7e77406c47ab781028b974c8d..affbc67c2ef6ecf74652124b3ebc8e2c54c301b8 100644 (file)
                interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ptn5150>;
-               status = "okay";
        };
 };
 
index 41c966147b9454d49502c351978b1992af2affbf..429be2bab8a2d5188dc9769ff7ad000e8769c53e 100644 (file)
@@ -57,7 +57,7 @@
        status = "okay";
 
        tpm@1 {
-               compatible = "tcg,tpm_tis-spi";
+               compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
                reg = <0x1>;
                spi-max-frequency = <36000000>;
        };
index 5e2cbaf27e0fc8dd44351e9426fb9df56ee52354..35ae0faa815bc5d436c2665882e7127bf5ff3bb1 100644 (file)
        };
 
        tpm@1 {
-               compatible = "tcg,tpm_tis-spi";
+               compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
                reg = <0x1>;
                spi-max-frequency = <36000000>;
        };
index 1cff0b829357ed56faf7ee77c5ab58dca09fe5eb..ce20de25980545921768ffbd246fd146bbd26767 100644 (file)
@@ -10,7 +10,7 @@
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&dailink_master>;
                simple-audio-card,mclk-fs = <256>;
-               simple-audio-card,name = "imx8mm-wm8904";
+               simple-audio-card,name = "verdin-wm8904";
                simple-audio-card,routing =
                        "Headphone Jack", "HPOUTL",
                        "Headphone Jack", "HPOUTR",
                        sound-dai = <&sai2>;
                };
        };
+
+       reg_usb_hub: regulator-usb-hub {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               regulator-name = "HUB_PWR_EN";
+       };
+
+       reg_pcie: regulator-pcie {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               regulator-name = "PCIE_1_PWR_EN";
+               startup-delay-us = <100000>;
+       };
 };
 
 /* Verdin SPI_1 */
        status = "okay";
 };
 
+&gpio5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 /* Current measurement into module VCC */
 &hwmon {
        status = "okay";
 
 /* Verdin PCIE_1 */
 &pcie0 {
+       vpcie-supply = <&reg_pcie>;
        status = "okay";
 };
 
        status = "okay";
 };
 
+/* We support turning off sleep moci on Dahlia */
+&reg_force_sleep_moci {
+       status = "disabled";
+};
+
 /* Verdin I2S_1 */
 &sai2 {
        status = "okay";
 
 /* Verdin USB_2 */
 &usbotg2 {
+       #address-cells = <1>;
+       #size-cells = <0>;
        disable-over-current;
        status = "okay";
+
+       usb-hub@1 {
+               compatible = "usb424,2744";
+               reg = <1>;
+               vdd-supply = <&reg_usb_hub>;
+       };
 };
 
 /* Verdin SD_1 */
index 3c4b8ca125e3211b172b2656301e02ebbee5b0f1..1d8d146d9eebad32de81c0f7860be52a4b6d7ef2 100644 (file)
@@ -10,7 +10,7 @@
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&dailink_master>;
                simple-audio-card,mclk-fs = <256>;
-               simple-audio-card,name = "imx8mm-nau8822";
+               simple-audio-card,name = "verdin-nau8822";
                simple-audio-card,routing =
                        "Headphones", "LHP",
                        "Headphones", "RHP",
        status = "okay";
 };
 
+&gpio5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 &gpio_expander_21 {
        status = "okay";
 };
index 1e28c78e381fc9c6da4c983d3e432c157ea7208d..763f069e8405442f2af7491ff810b8b2375248f2 100644 (file)
        pinctrl-0 = <&pinctrl_gpios_ext_yavia>;
 };
 
+&gpio5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 &hwmon_temp {
        status = "okay";
 };
index 6f0811587142d2725db959d100e7229c6ca82f02..4768b05fd7659ef348e958a6093198ccea6baebe 100644 (file)
                startup-delay-us = <200000>;
        };
 
+       /*
+        * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+        * peripherals on the carrier board powered.
+        * If more granularity or power saving is required this can be disabled
+        * in the carrier board device tree files.
+        */
+       reg_force_sleep_moci: regulator-force-sleep-moci {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "CTRL_SLEEP_MOCI#";
+       };
+
        reg_usb_otg1_vbus: regulator-usb-otg1 {
                compatible = "regulator-fixed";
                enable-active-high;
                          "SODIMM_212",
                          "SODIMM_151",
                          "SODIMM_153";
-
-       ctrl-sleep-moci-hog {
-               gpio-hog;
-               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
-               gpios = <1 GPIO_ACTIVE_HIGH>;
-               line-name = "CTRL_SLEEP_MOCI#";
-               output-high;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
-       };
 };
 
 /* On-module I2C */
index 8a1b42b94dce69d6d69a153b5298568bf7fbaf02..9535dedcef59b008d03fb14da75fa01c52be2d79 100644 (file)
                                                        remote-endpoint = <&lcdif_to_dsim>;
                                                };
                                        };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               mipi_dsi_out: endpoint {
+                                               };
+                                       };
                                };
                        };
 
                                reg = <0x32e40000 0x200>;
                                interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
-                               clock-names = "usb1_ctrl_root_clk";
                                assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
                                assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
                                phys = <&usbphynop1>;
                                reg = <0x32e50000 0x200>;
                                interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
-                               clock-names = "usb1_ctrl_root_clk";
                                assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
                                assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
                                phys = <&usbphynop2>;
index 000e2c0596df30cb46c1adeb4e5f66339308cf64..d25032e3ceabaa2919b7ce587d59b059c881170b 100644 (file)
                };
        };
 };
+
+&i2c2 {
+       hdmi@3d {
+               avdd-supply = <&buck5>;
+               dvdd-supply = <&buck5>;
+               pvdd-supply = <&buck5>;
+               a2vdd-supply = <&buck5>;
+               v1p2-supply = <&buck5>;
+       };
+};
+
+&i2c3 {
+       camera@3c {
+               DOVDD-supply = <&buck5>;
+       };
+};
index cc2ff59ac53b864b95f9067d11ca4421c7d5ff1d..6d85a0b052c9f5668bc8e7b486e5d0e369af3763 100644 (file)
                };
        };
 };
+
+&i2c2 {
+       hdmi@3d {
+               avdd-supply = <&buck5_reg>;
+               dvdd-supply = <&buck5_reg>;
+               pvdd-supply = <&buck5_reg>;
+               a2vdd-supply = <&buck5_reg>;
+               v1p2-supply = <&buck5_reg>;
+       };
+};
+
+&i2c3 {
+       camera@3c {
+               DOVDD-supply = <&buck5_reg>;
+       };
+};
index 0b71f50d936ecadb7564dde741bb2f19fba67f7f..41330210a05fcfa5fa326c1a3fbde9bf3953ce7c 100644 (file)
                };
        };
 };
+
+&i2c2 {
+       hdmi@3d {
+               avdd-supply = <&buck5>;
+               dvdd-supply = <&buck5>;
+               pvdd-supply = <&buck5>;
+               a2vdd-supply = <&buck5>;
+               v1p2-supply = <&buck5>;
+       };
+};
+
+&i2c3 {
+       camera@3c {
+               DOVDD-supply = <&buck5>;
+       };
+};
index 269e70f66a1331da780422dd6d3eb1402560d3c8..9e0259ddf4bca36966010bbcee0d7b06400e1c59 100644 (file)
@@ -30,7 +30,7 @@
 
                port {
                        hdmi_connector_in: endpoint {
-                               remote-endpoint = <&adv7533_out>;
+                               remote-endpoint = <&adv7535_out>;
                        };
                };
        };
                enable-active-high;
        };
 
+       reg_1v5: regulator-1v5 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_1V5";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+       };
+
+       reg_1v8: regulator-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       reg_vddext_3v3: regulator-vddext-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDEXT_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
        ir-receiver {
                compatible = "gpio-ir-receiver";
                gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
 
        hdmi@3d {
                compatible = "adi,adv7535";
-               reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>;
-               reg-names = "main", "cec", "edid", "packet";
+               reg = <0x3d>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
                adi,dsi-lanes = <4>;
-
-               adi,input-depth = <8>;
-               adi,input-colorspace = "rgb";
-               adi,input-clock = "1x";
-               adi,input-style = <1>;
-               adi,input-justification = "evenly";
+               v3p3-supply = <&reg_vddext_3v3>;
 
                ports {
                        #address-cells = <1>;
                        port@0 {
                                reg = <0>;
 
-                               adv7533_in: endpoint {
+                               adv7535_in: endpoint {
                                        remote-endpoint = <&dsi_out>;
                                };
                        };
                        port@1 {
                                reg = <1>;
 
-                               adv7533_out: endpoint {
+                               adv7535_out: endpoint {
                                        remote-endpoint = <&hdmi_connector_in>;
                                };
                        };
        };
 
        ptn5110: tcpc@50 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec1>;
                reg = <0x50>;
                assigned-clock-rates = <24000000>;
                powerdown-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
                reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+               AVDD-supply = <&reg_1v8>;
+               DVDD-supply = <&reg_1v5>;
 
                port {
                        ov5640_to_mipi_csi2: endpoint {
                        reg = <1>;
 
                        dsi_out: endpoint {
-                               remote-endpoint = <&adv7533_in>;
+                               remote-endpoint = <&adv7535_in>;
                                data-lanes = <1 2 3 4>;
                        };
                };
index a6b94d1957c92ac6bcc18667b477ca05eda8b1bc..3434b189fa583afc35899e1e508628c3c9822e63 100644 (file)
                interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ptn5150>;
-               status = "okay";
 
                port {
                        typec1_dr_sw: endpoint {
index 932c8b05c75fc06ea394bcdc0f8fbe049dade17d..a5f9cfb46e5dd76c7d8d7bde5915b746ce36ad02 100644 (file)
                                                        remote-endpoint = <&lcdif_to_dsim>;
                                                };
                                        };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               mipi_dsi_out: endpoint {
+                                               };
+                                       };
                                };
                        };
 
                                reg = <0x32e40000 0x200>;
                                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>;
                                assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
                                phys = <&usbphynop1>;
index a08057410bdef5b3a2572cb5c5e2fe6ea35b5522..e5d3901f29136f4051e55610045f1908a94eef57 100644 (file)
 &i2c3 {
        /* Connected to USB Hub */
        usb-typec@52 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                reg = <0x52>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec>;
index 2c19766ebf093fde85912660e1a4145812e4ab82..9b8f97a84e6197a93c5011a47f94e5e914d04479 100644 (file)
 };
 
 &i2c2 {
-       clock-frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c2>;
-       status = "okay";
 };
 
 &i2c3 {
index b11d694b98e1bc6818b40ca48f8d5bee2fd090c5..d241db3743a9c70ec38cf7b09625d0417dafb228 100644 (file)
        pinctrl-0 = <&pinctrl_eqos>;
        nvmem-cells = <&ethmac1>;
        nvmem-cell-names = "mac-address";
-       phy-supply = <&reg_baseboard_vdd3v3>;
        phy-handle = <&ethphy0>;
        phy-mode = "rgmii-id";
        status = "okay";
index b749e28e5ede5cf85f309f2f7903ebee44b41f98..ac7ec7533a3c8c7b28ec1e75616b55735ba9b306 100644 (file)
                                VDDIO-supply = <&reg_vdd_3p3v_awo>;
                        };
 
+                       csi2exp: gpio@24 {
+                               compatible = "nxp,pca9570";
+                               reg = <0x24>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               gpio-line-names =
+                                       "CSI2_#RESET", "CSI2_#PWDN",
+                                       "CSI_#PWDN", "CSI_#RESET";
+                       };
+
                        typec@3d {
                                compatible = "nxp,ptn5150";
                                reg = <0x3d>;
index 9beba8d6a0dfe4b1ec51015e0f1c12ebca2d8f1c..8be5b2a57f27f4c67c14e813f94c9b49d4303b5a 100644 (file)
 
        };
 
+       sound-hdmi {
+               compatible = "fsl,imx-audio-hdmi";
+               model = "audio-hdmi";
+               audio-cpu = <&aud2htx>;
+               hdmi-out;
+       };
+
+       sound-micfil {
+               compatible = "fsl,imx-audio-card";
+               model = "micfil-audio";
+
+               pri-dai-link {
+                       link-name = "micfil hifi";
+                       format = "i2s";
+
+                       cpu {
+                               sound-dai = <&micfil>;
+                       };
+               };
+       };
+
        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
        cpu-supply = <&reg_arm>;
 };
 
+&aud2htx {
+       status = "okay";
+};
+
 &eqos {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_eqos>;
        status = "okay";
 };
 
+&micfil {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pdm>;
+       assigned-clocks = <&clk IMX8MP_CLK_PDM>;
+       assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <196608000>;
+       status = "okay";
+};
+
 &mipi_dsi {
        samsung,esc-clock-frequency = <10000000>;
        status = "okay";
                >;
        };
 
+       pinctrl_pdm: pdmgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SAI5_RXC__AUDIOMIX_PDM_CLK         0xd6
+                       MX8MP_IOMUXC_SAI5_RXD0__AUDIOMIX_PDM_BIT_STREAM00       0xd6
+                       MX8MP_IOMUXC_SAI5_RXD1__AUDIOMIX_PDM_BIT_STREAM01       0xd6
+                       MX8MP_IOMUXC_SAI5_RXD2__AUDIOMIX_PDM_BIT_STREAM02       0xd6
+                       MX8MP_IOMUXC_SAI5_RXD3__AUDIOMIX_PDM_BIT_STREAM03       0xd6
+               >;
+       };
+
        pinctrl_pmic: pmicgrp {
                fsl,pins = <
                        MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03     0x000001c0
index 61c2a63efc6dbfa4bc2f81d7264392fe8178279d..0fd5c3abcdb7c4c4e7fbeb60ffafcb0c08681e94 100644 (file)
 };
 
 &i2c1 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c1>;
+       pinctrl-1 = <&pinctrl_i2c1_gpio>;
+       scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        clock-frequency = <400000>;
        status = "okay";
 
 };
 
 &i2c6 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c6>;
+       pinctrl-1 = <&pinctrl_i2c6_gpio>;
+       scl-gpios = <&gpio3 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio3 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
        clock-frequency = <400000>;
        status = "okay";
 
 
        pinctrl_i2c1: i2c1grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL                0x400001c3>,
-                       <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL                0x400001e0>,
+                       <MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA                0x400001e0>;
+       };
+
+       pinctrl_i2c1_gpio: i2c1gpiogrp {
+               fsl,pins =
+                       <MX8MP_IOMUXC_I2C1_SCL__GPIO5_IO14              0x1e0>,
+                       <MX8MP_IOMUXC_I2C1_SDA__GPIO5_IO15              0x1e0>;
        };
 
        pinctrl_i2c2: i2c2grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL                0x400001c3>,
-                       <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL                0x400001e0>,
+                       <MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA                0x400001e0>;
        };
 
        pinctrl_i2c3: i2c3grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL                0x400001c3>,
-                       <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL                0x400001e0>,
+                       <MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA                0x400001e0>;
        };
 
        pinctrl_i2c4: i2c4grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL                0x400001c3>,
-                       <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL                0x400001e0>,
+                       <MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA                0x400001e0>;
        };
 
        pinctrl_i2c5: i2c5grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL                0x400001c3>,
-                       <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL                0x400001e0>,
+                       <MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA                0x400001e0>;
        };
 
        pinctrl_i2c6: i2c6grp {
                fsl,pins =
-                       <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL               0x400001c3>,
-                       <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA                0x400001c3>;
+                       <MX8MP_IOMUXC_SAI5_RXFS__I2C6_SCL               0x400001e0>,
+                       <MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA                0x400001e0>;
+       };
+
+       pinctrl_i2c6_gpio: i2c6gpiogrp {
+               fsl,pins =
+                       <MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19             0x1e0>,
+                       <MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20              0x1e0>;
        };
 
        pinctrl_lcd0_backlight: lcd0-backlightgrp {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts b/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
new file mode 100644 (file)
index 0000000..5fd1614
--- /dev/null
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Emcraft Systems
+ * Copyright 2024 Gilles Talis <gilles.talis@gmail.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "imx8mp.dtsi"
+
+/ {
+       model = "Emcraft Systems i.MX8MPlus NavQ+ Kit";
+       compatible = "emcraft,imx8mp-navqp", "fsl,imx8mp";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_led>;
+
+               led-0 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_STATUS;
+                       gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       reg_usdhc2_vmmc: regulator-usdhc2 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               startup-delay-us = <100>;
+               off-on-delay-us = <12000>;
+       };
+};
+
+&A53_0 {
+       cpu-supply = <&buck2>;
+};
+
+&A53_1 {
+       cpu-supply = <&buck2>;
+};
+
+&A53_2 {
+       cpu-supply = <&buck2>;
+};
+
+&A53_3 {
+       cpu-supply = <&buck2>;
+};
+
+&eqos {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_eqos>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       status = "okay";
+
+       mdio {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+                       reset-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <1000>;
+                       reset-deassert-us = <10000>;
+                       qca,disable-smarteee;
+                       qca,disable-hibernation-mode;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic@25 {
+               compatible = "nxp,pca9450c";
+               reg = <0x25>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+
+               regulators {
+                       BUCK1 {
+                               regulator-name = "BUCK1";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <2187500>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <3125>;
+                       };
+
+                       buck2: BUCK2 {
+                               regulator-name = "BUCK2";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <2187500>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <3125>;
+                               nxp,dvs-run-voltage = <950000>;
+                               nxp,dvs-standby-voltage = <850000>;
+                       };
+
+                       BUCK4 {
+                               regulator-name = "BUCK4";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <3400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       BUCK5 {
+                               regulator-name = "BUCK5";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <3400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       BUCK6 {
+                               regulator-name = "BUCK6";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <3400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       LDO1 {
+                               regulator-name = "LDO1";
+                               regulator-min-microvolt = <1600000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       LDO2 {
+                               regulator-name = "LDO2";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1150000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       LDO3 {
+                               regulator-name = "LDO3";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       LDO4 {
+                               regulator-name = "LDO4";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       LDO5 {
+                               regulator-name = "LDO5";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+};
+
+&i2c4 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c4>;
+       status = "okay";
+
+       rtc@53 {
+               compatible = "nxp,pcf2131";
+               reg = <0x53>;
+       };
+};
+
+&uart2 {
+       /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+/* SD Card */
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+/* eMMC */
+&usdhc3 {
+       assigned-clocks = <&clk IMX8MP_CLK_USDHC3>;
+       assigned-clock-rates = <400000000>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_eqos: eqosgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC                             0x3
+                       MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO                           0x3
+                       MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0                       0x91
+                       MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1                       0x91
+                       MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2                       0x91
+                       MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3                       0x91
+                       MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK       0x91
+                       MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL                 0x91
+                       MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0                       0x1f
+                       MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1                       0x1f
+                       MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2                       0x1f
+                       MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3                       0x1f
+                       MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL                 0x1f
+                       MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK       0x1f
+                       MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22                               0x110
+               >;
+       };
+
+       pinctrl_gpio_led: gpioledgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16                           0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL                                 0x400001c3
+                       MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA                                 0x400001c3
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL                                 0x400001c3
+                       MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA                                 0x400001c3
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL                                 0x400001c3
+                       MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA                                 0x400001c3
+               >;
+       };
+
+       pinctrl_i2c4: i2c4grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL                                 0x400001c3
+                       MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA                                 0x400001c3
+               >;
+       };
+
+       pinctrl_pmic: pmicgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03                             0x41
+               >;
+       };
+
+       pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19                            0x41
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX                            0x49
+                       MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX                            0x49
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK                                0x190
+                       MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD                                0x1d0
+                       MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0                            0x1d0
+                       MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1                            0x1d0
+                       MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2                            0x1d0
+                       MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3                            0x1d0
+                       MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT                         0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK                                0x194
+                       MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD                                0x1d4
+                       MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0                            0x1d4
+                       MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1                            0x1d4
+                       MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2                            0x1d4
+                       MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3                            0x1d4
+                       MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT                         0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK                                0x196
+                       MX8MP_IOMUXC_SD2_CMD__USDHC2_CMD                                0x1d6
+                       MX8MP_IOMUXC_SD2_DATA0__USDHC2_DATA0                            0x1d6
+                       MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1                            0x1d6
+                       MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2                            0x1d6
+                       MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3                            0x1d6
+                       MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT                         0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_SD2_CD_B__GPIO2_IO12                               0x1c4
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK                              0x190
+                       MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD                              0x1d0
+                       MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0                          0x1d0
+                       MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1                          0x1d0
+                       MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2                          0x1d0
+                       MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3                          0x1d0
+                       MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4                            0x1d0
+                       MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5                           0x1d0
+                       MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6                           0x1d0
+                       MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7                             0x1d0
+                       MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE                          0x190
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK                              0x194
+                       MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD                              0x1d4
+                       MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0                          0x1d4
+                       MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1                          0x1d4
+                       MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2                          0x1d4
+                       MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3                          0x1d4
+                       MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4                            0x1d4
+                       MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5                           0x1d4
+                       MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6                           0x1d4
+                       MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7                             0x1d4
+                       MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE                          0x194
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK                              0x196
+                       MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD                              0x1d6
+                       MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0                          0x1d6
+                       MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1                          0x1d6
+                       MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2                          0x1d6
+                       MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3                          0x1d6
+                       MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4                            0x1d6
+                       MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5                           0x1d6
+                       MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6                           0x1d6
+                       MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7                             0x1d6
+                       MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE                          0x196
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B                           0xc6
+               >;
+       };
+};
index 86d3da36e4f3eecf64c0168c825baee86dfdab3f..c51ed7d991d186ca2a89c4dcaf7db7c63b435f57 100644 (file)
                };
        };
 
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               label = "X44";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_out>;
+                       };
+               };
+       };
+
        display: display {
                /*
                 * Display is not fixed, so compatible has to be added from
                          "", "", "", "";
 };
 
+&hdmi_pvi {
+       status = "okay";
+};
+
+&hdmi_tx {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hdmi>;
+       status = "okay";
+
+       ports {
+               port@1 {
+                       hdmi_tx_out: endpoint {
+                               remote-endpoint = <&hdmi_connector_in>;
+                       };
+               };
+       };
+};
+
+&hdmi_tx_phy {
+       status = "okay";
+};
+
 &i2c2 {
        clock-frequency = <384000>;
        pinctrl-names = "default", "gpio";
        status = "okay";
 };
 
+&lcdif3 {
+       status = "okay";
+};
+
 &pcf85063 {
        /* RTC_EVENT# is connected on MBa8MPxL */
        pinctrl-names = "default";
index e7bf032265e010eecb031e8c9dabe958077a31f1..2f740d74707bdfd612a977217b298f50562abacf 100644 (file)
@@ -68,7 +68,7 @@
        status = "okay";
 
        tpm@1 {
-               compatible = "tcg,tpm_tis-spi";
+               compatible = "atmel,attpm20p", "tcg,tpm_tis-spi";
                reg = <0x1>;
                spi-max-frequency = <36000000>;
        };
index f24b14744799e16bb1145738bfb18fd8343c00ee..5ab3ffe9931d4a3ca52d6ff45b3867f6c497814b 100644 (file)
@@ -8,6 +8,10 @@
 #include <dt-bindings/phy/phy-imx8-pcie.h>
 
 / {
+       aliases {
+               ethernet1 = &eth1;
+       };
+
        connector {
                compatible = "gpio-usb-b-connector", "usb-b-connector";
                pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pcie0>;
        reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
        status = "okay";
+
+       pcie@0,0 {
+               reg = <0x0000 0 0 0 0>;
+               device_type = "pci";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               ranges;
+
+               pcie@0,0 {
+                       reg = <0x0000 0 0 0 0>;
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       pcie@3,0 {
+                               reg = <0x1800 0 0 0 0>;
+                               device_type = "pci";
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+
+                               eth1: ethernet@0,0 {
+                                       reg = <0x0000 0 0 0 0>;
+                                       #address-cells = <3>;
+                                       #size-cells = <2>;
+                                       ranges;
+                                       local-mac-address = [00 00 00 00 00 00];
+                               };
+                       };
+               };
+       };
 };
 
 /* GPS */
index f5491a608b2f3793ca410871fda7e5005db661e1..dec57fad6828551c0bc1b05186d9424396b3dfb7 100644 (file)
@@ -8,6 +8,10 @@
 #include <dt-bindings/phy/phy-imx8-pcie.h>
 
 / {
+       aliases {
+               ethernet1 = &eth1;
+       };
+
        connector {
                compatible = "gpio-usb-b-connector", "usb-b-connector";
                pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pcie0>;
        reset-gpio = <&gpio4 29 GPIO_ACTIVE_LOW>;
        status = "okay";
+
+       pcie@0,0 {
+               reg = <0x0000 0 0 0 0>;
+               device_type = "pci";
+               #address-cells = <3>;
+               #size-cells = <2>;
+               ranges;
+
+               pcie@0,0 {
+                       reg = <0x0000 0 0 0 0>;
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       pcie@4,0 {
+                               reg = <0x2000 0 0 0 0>;
+                               device_type = "pci";
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+
+                               eth1: ethernet@0,0 {
+                                       reg = <0x0000 0 0 0 0>;
+                                       #address-cells = <3>;
+                                       #size-cells = <2>;
+                                       ranges;
+                                       local-mac-address = [00 00 00 00 00 00];
+                               };
+                       };
+               };
+       };
 };
 
 /* GPS */
index 270a9114da97f80cd942cbbc5b85c87759dfe9b5..edf22ff549a476e441c8764356d4c4267a2a39c1 100644 (file)
        status = "okay";
 
        ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                port@0 {
+                       reg = <0>;
+
                        mipi_csi_0_in: endpoint {
                                remote-endpoint = <&imx219_to_mipi_csi2>;
                                data-lanes = <1 2>;
                        };
                };
+
+               port@1 {
+                       reg = <1>;
+
+                       mipi_csi_0_out: endpoint {
+                               remote-endpoint = <&isi_in_0>;
+                       };
+               };
        };
 };
 
index cae586cd45bdd59aa479e70bb290fc50b0392a3c..a77e9a44d9fa25200564aa9be1b073b576954876 100644 (file)
                                label = "vdd_dram";
                        };
 
+                       channel@9e {
+                               gw,mode = <2>;
+                               reg = <0x9e>;
+                               label = "vdd_1p0";
+                       };
+
                        channel@a2 {
                                gw,mode = <2>;
                                reg = <0xa2>;
index 7e9e4b13b5c50dd6ebb6c508b187ec33160ae057..6e6b9c2c46406fc3691193e6874eb85fd8d28065 100644 (file)
@@ -10,7 +10,7 @@
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&codec_dai>;
                simple-audio-card,mclk-fs = <256>;
-               simple-audio-card,name = "imx8mp-wm8904";
+               simple-audio-card,name = "verdin-wm8904";
                simple-audio-card,routing =
                        "Headphone Jack", "HPOUTL",
                        "Headphone Jack", "HPOUTR",
                        sound-dai = <&sai1>;
                };
        };
+
+       reg_usb_hub: regulator-usb-hub {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               regulator-name = "HUB_PWR_EN";
+       };
+
+       reg_pcie: regulator-pcie {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               regulator-name = "PCIE_1_PWR_EN";
+               startup-delay-us = <100000>;
+       };
 };
 
 &backlight {
        status = "okay";
 };
 
+&gpio4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 /* Current measurement into module VCC */
 &hwmon {
        status = "okay";
        };
 };
 
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+       status = "okay";
+};
+
 /* Verdin PCIE_1 */
 &pcie {
+       vpcie-supply = <&reg_pcie>;
        status = "okay";
 };
 
        vin-supply = <&reg_3p3v>;
 };
 
+/* We support turning off sleep moci on Dahlia */
+&reg_force_sleep_moci {
+       status = "disabled";
+};
+
 /* Verdin I2S_1 */
 &sai1 {
        assigned-clocks = <&clk IMX8MP_CLK_SAI1>;
        status = "okay";
 };
 
+&usb_dwc3_1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       usb_hub_3_0: usb-hub@1 {
+               compatible = "usb424,5744";
+               reg = <1>;
+               peer-hub = <&usb_hub_2_0>;
+               vdd-supply = <&reg_usb_hub>;
+       };
+
+       usb_hub_2_0: usb-hub@2 {
+               compatible = "usb424,2744";
+               reg = <2>;
+               peer-hub = <&usb_hub_3_0>;
+               vdd-supply = <&reg_usb_hub>;
+       };
+};
+
 /* Verdin SD_1 */
 &usdhc2 {
        status = "okay";
index a509b2b7fa857058069592b86d62022bb85d653a..42ed44a1171101964e952441df49e4f70a314da3 100644 (file)
@@ -22,7 +22,7 @@
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&codec_dai>;
                simple-audio-card,mclk-fs = <256>;
-               simple-audio-card,name = "imx8mp-nau8822";
+               simple-audio-card,name = "verdin-nau8822";
                simple-audio-card,routing =
                        "Headphones", "LHP",
                        "Headphones", "RHP",
        status = "okay";
 };
 
+&gpio4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 &gpio_expander_21 {
        status = "okay";
        vcc-supply = <&reg_1p8v>;
        };
 };
 
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+       status = "okay";
+};
+
 /* Verdin PCIE_1 */
 &pcie {
        status = "okay";
index 8482393f3cac5e994f889106aafb9d4d91ddf271..1d15f7449c58004624ec9429c997a62a20c2e3ec 100644 (file)
        status = "okay";
 };
 
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+       status = "okay";
+};
+
 /* Verdin PCIE_1 */
 &pcie {
        status = "okay";
index db1722f0d80ef96e8609dae887d1f5f20b145c87..a7b261ff3e4cd8f03a7e6c2c4d41da4284c081d6 100644 (file)
        status = "okay";
 };
 
+&gpio4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+};
+
 &hwmon_temp {
        status = "okay";
 };
        status = "okay";
 };
 
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+       status = "okay";
+};
+
 /* Verdin PCIE_1 */
 &pcie {
        status = "okay";
index faa17cbbe2fdae53945194e2861a4dbfec8d1838..aef4bef4bccddb68af23f626065d2940253564ae 100644 (file)
                vin-supply = <&reg_vdd_3v3>;
        };
 
+       /*
+        * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+        * peripherals on the carrier board powered.
+        * If more granularity or power saving is required this can be disabled
+        * in the carrier board device tree files.
+        */
+       reg_force_sleep_moci: regulator-force-sleep-moci {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "CTRL_SLEEP_MOCI#";
+       };
+
        reg_usb1_vbus: regulator-usb1-vbus {
                compatible = "regulator-fixed";
                enable-active-high;
                          "SODIMM_256",
                          "SODIMM_48",
                          "SODIMM_44";
-
-       ctrl-sleep-moci-hog {
-               gpio-hog;
-               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
-               gpios = <29 GPIO_ACTIVE_HIGH>;
-               line-name = "CTRL_SLEEP_MOCI#";
-               output-high;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
-       };
 };
 
 /* On-module I2C */
        };
 };
 
-/* TODO: Verdin I2C_3_HDMI */
-
 /* Verdin I2C_4_CSI */
 &i2c3 {
        clock-frequency = <400000>;
        };
 };
 
+/* Verdin I2C_3_HDMI */
+&i2c5 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default", "gpio";
+       pinctrl-0 = <&pinctrl_i2c5>;
+       pinctrl-1 = <&pinctrl_i2c5_gpio>;
+       scl-gpios = <&gpio3 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio3 27 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
 /* Verdin PCIE_1 */
 &pcie {
        pinctrl-names = "default";
        pinctrl_hdmi_hog: hdmihoggrp {
                fsl,pins =
                        <MX8MP_IOMUXC_HDMI_CEC__HDMIMIX_HDMI_CEC        0x40000019>,    /* SODIMM 63 */
-                       <MX8MP_IOMUXC_HDMI_DDC_SCL__HDMIMIX_HDMI_SCL    0x400001c3>,    /* SODIMM 59 */
-                       <MX8MP_IOMUXC_HDMI_DDC_SDA__HDMIMIX_HDMI_SDA    0x400001c3>,    /* SODIMM 57 */
                        <MX8MP_IOMUXC_HDMI_HPD__HDMIMIX_HDMI_HPD        0x40000019>;    /* SODIMM 61 */
        };
 
                        <MX8MP_IOMUXC_I2C4_SDA__GPIO5_IO21              0x400001c6>;    /* SODIMM 12 */
        };
 
+       /* Verdin I2C_3_HDMI */
+       pinctrl_i2c5: i2c5grp {
+               fsl,pins =
+                       <MX8MP_IOMUXC_HDMI_DDC_SCL__I2C5_SCL            0x400001c6>,    /* SODIMM 59 */
+                       <MX8MP_IOMUXC_HDMI_DDC_SDA__I2C5_SDA            0x400001c6>;    /* SODIMM 57 */
+       };
+
+       pinctrl_i2c5_gpio: i2c5gpiogrp {
+               fsl,pins =
+                       <MX8MP_IOMUXC_HDMI_DDC_SCL__GPIO3_IO26          0x400001c6>,    /* SODIMM 59 */
+                       <MX8MP_IOMUXC_HDMI_DDC_SDA__GPIO3_IO27          0x400001c6>;    /* SODIMM 57 */
+       };
+
        /* Verdin I2S_2_BCLK (TOUCH_RESET#) */
        pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
                fsl,pins =
index 8141926e4ef1424639a3196337c7e006f5f6995e..b92abb5a5c536f41bb1017690135e098bec98415 100644 (file)
                                                         <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
                                        };
 
+                                       pgc_hdmimix: power-domain@14 {
+                                               #power-domain-cells = <0>;
+                                               reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+                                               clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+                                                        <&clk IMX8MP_CLK_HDMI_APB>;
+                                               assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+                                                                 <&clk IMX8MP_CLK_HDMI_APB>;
+                                               assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+                                                                        <&clk IMX8MP_SYS_PLL1_133M>;
+                                               assigned-clock-rates = <500000000>, <133000000>;
+                                       };
+
+                                       pgc_hdmi_phy: power-domain@15 {
+                                               #power-domain-cells = <0>;
+                                               reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
+                                       };
+
                                        pgc_mipi_phy2: power-domain@16 {
                                                #power-domain-cells = <0>;
                                                reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
                                        status = "disabled";
                                };
 
+                               aud2htx: aud2htx@30cb0000 {
+                                       compatible = "fsl,imx8mp-aud2htx";
+                                       reg = <0x30cb0000 0x10000>;
+                                       interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+                                       clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG>;
+                                       clock-names = "bus";
+                                       dmas = <&sdma2 26 2 0>;
+                                       dma-names = "tx";
+                                       status = "disabled";
+                               };
                        };
 
                        sdma3: dma-controller@30e00000 {
                                compatible = "fsl,imx8mp-mipi-csi2", "fsl,imx8mm-mipi-csi2";
                                reg = <0x32e40000 0x10000>;
                                interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
-                               clock-frequency = <500000000>;
+                               clock-frequency = <266000000>;
                                clocks = <&clk IMX8MP_CLK_MEDIA_APB_ROOT>,
                                         <&clk IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT>,
                                         <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT>,
                                                  <&clk IMX8MP_CLK_MEDIA_MIPI_PHY1_REF>;
                                assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_1000M>,
                                                         <&clk IMX8MP_CLK_24M>;
-                               assigned-clock-rates = <500000000>;
+                               assigned-clock-rates = <266000000>;
                                power-domains = <&media_blk_ctrl IMX8MP_MEDIABLK_PD_MIPI_CSI2_1>;
                                status = "disabled";
 
                                                        remote-endpoint = <&lcdif1_to_dsim>;
                                                };
                                        };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               mipi_dsi_out: endpoint {
+                                               };
+                                       };
                                };
                        };
 
                                #power-domain-cells = <1>;
                                #clock-cells = <0>;
                        };
+
+                       hdmi_blk_ctrl: blk-ctrl@32fc0000 {
+                               compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+                               reg = <0x32fc0000 0x1000>;
+                               clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                                        <&clk IMX8MP_CLK_HDMI_ROOT>,
+                                        <&clk IMX8MP_CLK_HDMI_REF_266M>,
+                                        <&clk IMX8MP_CLK_HDMI_24M>,
+                                        <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+                               clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+                               power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+                                               <&pgc_hdmimix>, <&pgc_hdmimix>,
+                                               <&pgc_hdmimix>, <&pgc_hdmimix>,
+                                               <&pgc_hdmimix>, <&pgc_hdmi_phy>,
+                                               <&pgc_hdmimix>, <&pgc_hdmimix>;
+                               power-domain-names = "bus", "irqsteer", "lcdif",
+                                                    "pai", "pvi", "trng",
+                                                    "hdmi-tx", "hdmi-tx-phy",
+                                                    "hdcp", "hrv";
+                               #power-domain-cells = <1>;
+                       };
+
+                       irqsteer_hdmi: interrupt-controller@32fc2000 {
+                               compatible = "fsl,imx-irqsteer";
+                               reg = <0x32fc2000 0x1000>;
+                               interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               fsl,channel = <1>;
+                               fsl,num-irqs = <64>;
+                               clocks = <&clk IMX8MP_CLK_HDMI_APB>;
+                               clock-names = "ipg";
+                               power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_IRQSTEER>;
+                       };
+
+                       hdmi_pvi: display-bridge@32fc4000 {
+                               compatible = "fsl,imx8mp-hdmi-pvi";
+                               reg = <0x32fc4000 0x1000>;
+                               interrupt-parent = <&irqsteer_hdmi>;
+                               interrupts = <12>;
+                               power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_PVI>;
+                               status = "disabled";
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+                                               pvi_from_lcdif3: endpoint {
+                                                       remote-endpoint = <&lcdif3_to_pvi>;
+                                               };
+                                       };
+
+                                       port@1 {
+                                               reg = <1>;
+                                               pvi_to_hdmi_tx: endpoint {
+                                                       remote-endpoint = <&hdmi_tx_from_pvi>;
+                                               };
+                                       };
+                               };
+                       };
+
+                       lcdif3: display-controller@32fc6000 {
+                               compatible = "fsl,imx8mp-lcdif";
+                               reg = <0x32fc6000 0x1000>;
+                               interrupt-parent = <&irqsteer_hdmi>;
+                               interrupts = <8>;
+                               clocks = <&hdmi_tx_phy>,
+                                        <&clk IMX8MP_CLK_HDMI_APB>,
+                                        <&clk IMX8MP_CLK_HDMI_ROOT>;
+                               clock-names = "pix", "axi", "disp_axi";
+                               power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_LCDIF>;
+                               status = "disabled";
+
+                               port {
+                                       lcdif3_to_pvi: endpoint {
+                                               remote-endpoint = <&pvi_from_lcdif3>;
+                                       };
+                               };
+                       };
+
+                       hdmi_tx: hdmi@32fd8000 {
+                               compatible = "fsl,imx8mp-hdmi-tx";
+                               reg = <0x32fd8000 0x7eff>;
+                               interrupt-parent = <&irqsteer_hdmi>;
+                               interrupts = <0>;
+                               clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                                        <&clk IMX8MP_CLK_HDMI_REF_266M>,
+                                        <&clk IMX8MP_CLK_32K>,
+                                        <&hdmi_tx_phy>;
+                               clock-names = "iahb", "isfr", "cec", "pix";
+                               assigned-clocks = <&clk IMX8MP_CLK_HDMI_REF_266M>;
+                               assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_266M>;
+                               power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX>;
+                               reg-io-width = <1>;
+                               status = "disabled";
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+
+                                               hdmi_tx_from_pvi: endpoint {
+                                                       remote-endpoint = <&pvi_to_hdmi_tx>;
+                                               };
+                                       };
+
+                                       port@1 {
+                                               reg = <1>;
+                                               /* Point endpoint to the HDMI connector */
+                                       };
+                               };
+                       };
+
+                       hdmi_tx_phy: phy@32fdff00 {
+                               compatible = "fsl,imx8mp-hdmi-phy";
+                               reg = <0x32fdff00 0x100>;
+                               clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+                                        <&clk IMX8MP_CLK_HDMI_24M>;
+                               clock-names = "apb", "ref";
+                               assigned-clocks = <&clk IMX8MP_CLK_HDMI_24M>;
+                               assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+                               power-domains = <&hdmi_blk_ctrl IMX8MP_HDMIBLK_PD_HDMI_TX_PHY>;
+                               #clock-cells = <0>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
                };
 
                pcie: pcie@33800000 {
index 366693f31992ef00ef5cdbbc0af9ec8d3eef4a47..e92b5d5a66b59eb2ed404e883cec9ec915a39bfd 100644 (file)
@@ -42,7 +42,7 @@
        status = "okay";
 
        typec_ptn5100: usb-typec@50 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                reg = <0x50>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec>;
index 8055a2c23035498f6a855a654e9379d60f95b3bd..b268ba7a0e12a3f8dd6090412dc337529bd51a81 100644 (file)
        };
 
        typec_ptn5100: usb-typec@52 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                reg = <0x52>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec>;
index c6dc3ba0d43b23f88af1656a28f1b3f1ccab0b98..e03186bbc415248a1e23c5fe83638c04bfcb9932 100644 (file)
                                                        remote-endpoint = <&lcdif_mipi_dsi>;
                                                };
                                        };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               mipi_dsi_out: endpoint {
+                                               };
+                                       };
                                };
                        };
 
index 77ac0efdfaadaec7b5edc1c83bbe8393e67ef6dc..5c6b39c6933fc4f108e20c98b0f9a03706e583f6 100644 (file)
                gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>;
                enable-active-high;
        };
+
+       reg_vref_1v8: regulator-adc-vref {
+               compatible = "regulator-fixed";
+               regulator-name = "vref_1v8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+};
+
+&adc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc0>;
+       vref-supply = <&reg_vref_1v8>;
+       status = "okay";
 };
 
 &i2c1 {
        status = "okay";
 };
 
+&lpspi2 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpspi2 &pinctrl_lpspi2_cs>;
+       cs-gpios = <&lsio_gpio3 10 GPIO_ACTIVE_LOW>;
+       status = "okay";
+
+       spidev0: spi@0 {
+               reg = <0>;
+               compatible = "rohm,dh2228fv";
+               spi-max-frequency = <30000000>;
+       };
+};
+
+&flexspi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexspi0>;
+       status = "okay";
+
+       flash0: flash@0 {
+               reg = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <133000000>;
+               spi-tx-bus-width = <8>;
+               spi-rx-bus-width = <8>;
+       };
+};
+
 &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_fec1>;
                >;
        };
 
+       pinctrl_adc0: adc0grp {
+               fsl,pins = <
+                       IMX8QM_ADC_IN0_DMA_ADC0_IN0                             0xc0000060
+               >;
+       };
+
        pinctrl_fec1: fec1grp {
                fsl,pins = <
                        IMX8QM_ENET0_MDC_CONN_ENET0_MDC                         0x06000020
                >;
        };
 
+       pinctrl_lpspi2: lpspi2grp {
+               fsl,pins = <
+                       IMX8QM_SPI2_SCK_DMA_SPI2_SCK            0x06000040
+                       IMX8QM_SPI2_SDO_DMA_SPI2_SDO            0x06000040
+                       IMX8QM_SPI2_SDI_DMA_SPI2_SDI            0x06000040
+               >;
+       };
+
+       pinctrl_lpspi2_cs: lpspi2csgrp {
+               fsl,pins = <
+                       IMX8QM_SPI2_CS0_LSIO_GPIO3_IO10         0x21
+               >;
+       };
+
+       pinctrl_flexspi0: flexspi0grp {
+               fsl,pins = <
+                       IMX8QM_QSPI0A_DATA0_LSIO_QSPI0A_DATA0     0x06000021
+                       IMX8QM_QSPI0A_DATA1_LSIO_QSPI0A_DATA1     0x06000021
+                       IMX8QM_QSPI0A_DATA2_LSIO_QSPI0A_DATA2     0x06000021
+                       IMX8QM_QSPI0A_DATA3_LSIO_QSPI0A_DATA3     0x06000021
+                       IMX8QM_QSPI0A_DQS_LSIO_QSPI0A_DQS         0x06000021
+                       IMX8QM_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B     0x06000021
+                       IMX8QM_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B     0x06000021
+                       IMX8QM_QSPI0A_SCLK_LSIO_QSPI0A_SCLK       0x06000021
+                       IMX8QM_QSPI0B_SCLK_LSIO_QSPI0B_SCLK       0x06000021
+                       IMX8QM_QSPI0B_DATA0_LSIO_QSPI0B_DATA0     0x06000021
+                       IMX8QM_QSPI0B_DATA1_LSIO_QSPI0B_DATA1     0x06000021
+                       IMX8QM_QSPI0B_DATA2_LSIO_QSPI0B_DATA2     0x06000021
+                       IMX8QM_QSPI0B_DATA3_LSIO_QSPI0B_DATA3     0x06000021
+                       IMX8QM_QSPI0B_DQS_LSIO_QSPI0B_DQS         0x06000021
+                       IMX8QM_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B     0x06000021
+                       IMX8QM_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B     0x06000021
+               >;
+       };
+
        pinctrl_lpuart0: lpuart0grp {
                fsl,pins = <
                        IMX8QM_UART0_RX_DMA_UART0_RX                            0x06000020
index 8360bb851ac03f4a2f55e727ba7b2ec39a9e9828..cee13e58762cb532cb715fc426bae75332893b69 100644 (file)
                        };
                };
        };
+
+       sound-wm8960 {
+               compatible = "fsl,imx-audio-wm8960";
+               model = "wm8960-audio";
+               audio-cpu = <&sai1>;
+               audio-codec = <&wm8960>;
+               hp-det-gpio = <&lsio_gpio1 0 GPIO_ACTIVE_HIGH>;
+               audio-routing = "Headphone Jack", "HP_L",
+                               "Headphone Jack", "HP_R",
+                               "Ext Spk", "SPK_LP",
+                               "Ext Spk", "SPK_LN",
+                               "Ext Spk", "SPK_RP",
+                               "Ext Spk", "SPK_RN",
+                               "LINPUT1", "Mic Jack",
+                               "Mic Jack", "MICB";
+       };
 };
 
 &dsp {
        };
 
        ptn5110: tcpc@50 {
-               compatible = "nxp,ptn5110";
+               compatible = "nxp,ptn5110", "tcpci";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_typec>;
                reg = <0x50>;
 
 };
 
+&cm40_i2c {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <100000>;
+       pinctrl-names = "default", "gpio";
+       pinctrl-0 = <&pinctrl_cm40_i2c>;
+       pinctrl-1 = <&pinctrl_cm40_i2c_gpio>;
+       scl-gpios = <&lsio_gpio1 10 GPIO_ACTIVE_HIGH>;
+       sda-gpios = <&lsio_gpio1 9 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+       wm8960: audio-codec@1a {
+               compatible = "wlf,wm8960";
+               reg = <0x1a>;
+               clocks = <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+               clock-names = "mclk";
+               assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+                                 <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+                                 <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+                                 <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+               assigned-clock-rates = <786432000>,
+                                      <49152000>,
+                                      <12288000>,
+                                      <12288000>;
+               wlf,shared-lrclk;
+               wlf,hp-cfg = <2 2 3>;
+               wlf,gpio-cfg = <1 3>;
+       };
+
+       pca6416: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&cm40_intmux {
+       status = "okay";
+};
+
 &lpuart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lpuart0>;
        status = "okay";
 };
 
+&sai0 {
+       #sound-dai-cells = <0>;
+       assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+                         <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+                         <&sai0_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sai0>;
+       status = "okay";
+};
+
+&sai1 {
+       assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+                         <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+                         <&sai1_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sai1>;
+       status = "okay";
+};
+
+&sai4 {
+       assigned-clocks = <&acm IMX_ADMA_ACM_SAI4_MCLK_SEL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+                         <&sai4_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+       fsl,sai-asynchronous;
+       status = "okay";
+};
+
+&sai5 {
+       assigned-clocks = <&acm IMX_ADMA_ACM_SAI5_MCLK_SEL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_PLL>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_SLV_BUS>,
+                         <&clk IMX_SC_R_AUDIO_PLL_1 IMX_SC_PM_CLK_MST_BUS>,
+                         <&sai5_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-parents = <&aud_pll_div1_lpcg IMX_LPCG_CLK_0>;
+       assigned-clock-rates = <0>, <786432000>, <98304000>, <12288000>, <98304000>;
+       fsl,sai-asynchronous;
+       status = "okay";
+};
+
 &thermal_zones {
        pmic-thermal {
                polling-delay-passive = <250>;
 };
 
 &iomuxc {
+
+       pinctrl_cm40_i2c: cm40i2cgrp {
+               fsl,pins = <
+                       IMX8QXP_ADC_IN1_M40_I2C0_SDA                            0x0600004c
+                       IMX8QXP_ADC_IN0_M40_I2C0_SCL                            0x0600004c
+               >;
+       };
+
+       pinctrl_cm40_i2c_gpio: cm40i2cgpio-grp {
+               fsl,pins = <
+                       IMX8QXP_ADC_IN1_LSIO_GPIO1_IO09                         0xc600004c
+                       IMX8QXP_ADC_IN0_LSIO_GPIO1_IO10                         0xc600004c
+               >;
+       };
+
        pinctrl_fec1: fec1grp {
                fsl,pins = <
                        IMX8QXP_ENET0_MDC_CONN_ENET0_MDC                        0x06000020
                >;
        };
 
+       pinctrl_sai0: sai0grp {
+               fsl,pins = <
+                       IMX8QXP_SAI0_TXD_ADMA_SAI0_TXD          0x06000060
+                       IMX8QXP_SAI0_RXD_ADMA_SAI0_RXD          0x06000040
+                       IMX8QXP_SAI0_TXC_ADMA_SAI0_TXC          0x06000040
+                       IMX8QXP_SAI0_TXFS_ADMA_SAI0_TXFS        0x06000040
+               >;
+       };
+
+       pinctrl_sai1: sai1grp {
+               fsl,pins = <
+                       IMX8QXP_SAI1_RXD_ADMA_SAI1_RXD     0x06000040
+                       IMX8QXP_SAI1_RXC_ADMA_SAI1_TXC     0x06000040
+                       IMX8QXP_SAI1_RXFS_ADMA_SAI1_TXFS   0x06000040
+                       IMX8QXP_SPI0_CS1_ADMA_SAI1_TXD     0x06000060
+                       IMX8QXP_SPI2_CS0_LSIO_GPIO1_IO00   0x06000040
+               >;
+       };
+
        pinctrl_usdhc1: usdhc1grp {
                fsl,pins = <
                        IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK                        0x06000041
index 10e16d84c0c3b7caa9a3c43d0483a3459cca4a44..0313f295de2e9310fe6f1d5fc4ccaed108da2f3a 100644 (file)
        /* sorted in register address */
        #include "imx8-ss-img.dtsi"
        #include "imx8-ss-vpu.dtsi"
+       #include "imx8-ss-cm40.dtsi"
        #include "imx8-ss-gpu0.dtsi"
        #include "imx8-ss-adma.dtsi"
        #include "imx8-ss-conn.dtsi"
index 24bb253b938de54d658cba31918a468e8a5ee155..e937e5f8fa8b280ba58e1280b05051809ac3e99b 100644 (file)
        pinctrl-1 = <&pinctrl_lpi2c7>;
        status = "okay";
 
+       ptn5150_1: typec@1d {
+               compatible = "nxp,ptn5150";
+               reg = <0x1d>;
+               int-gpios = <&gpiof 3 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_typec1>;
+               status = "disabled";
+       };
+
        pcal6408: gpio@21 {
                compatible = "nxp,pcal9554b";
                reg = <0x21>;
                gpio-controller;
                #gpio-cells = <2>;
        };
+
+       ptn5150_2: typec@3d {
+               compatible = "nxp,ptn5150";
+               reg = <0x3d>;
+               int-gpios = <&gpiof 5 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_typec2>;
+               status = "disabled";
+       };
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb1>;
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       over-current-active-low;
+       status = "okay";
+};
+
+&usbphy1 {
+       fsl,tx-d-cal = <110>;
+       status = "okay";
+};
+
+&usbmisc1 {
+       status = "okay";
+};
+
+&usbotg2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb2>;
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       over-current-active-low;
+       status = "okay";
+};
+
+&usbphy2 {
+       fsl,tx-d-cal = <110>;
+       status = "okay";
+};
+
+&usbmisc2 {
+       status = "okay";
 };
 
 &usdhc0 {
                >;
        };
 
+       pinctrl_typec1: typec1grp {
+               fsl,pins = <
+                       MX8ULP_PAD_PTF3__PTF3           0x3
+               >;
+       };
+
+       pinctrl_typec2: typec2grp {
+               fsl,pins = <
+                       MX8ULP_PAD_PTF5__PTF5           0x3
+               >;
+       };
+
+       pinctrl_usb1: usb1grp {
+               fsl,pins = <
+                       MX8ULP_PAD_PTF2__USB0_ID        0x10003
+                       MX8ULP_PAD_PTF4__USB0_OC        0x10003
+               >;
+       };
+
+       pinctrl_usb2: usb2grp {
+               fsl,pins = <
+                       MX8ULP_PAD_PTD23__USB1_ID       0x10003
+                       MX8ULP_PAD_PTF6__USB1_OC        0x10003
+               >;
+       };
+
        pinctrl_usdhc0: usdhc0grp {
                fsl,pins = <
                        MX8ULP_PAD_PTD1__SDHC0_CMD      0x3
index c4a0082f30d3164456e1a1bc8856cb6a378709e0..e32d5afcf4a96218ad5fabeb20447a5b09beec1d 100644 (file)
                                #reset-cells = <1>;
                        };
 
+                       crypto: crypto@292e0000 {
+                               compatible = "fsl,sec-v4.0";
+                               reg = <0x292e0000 0x10000>;
+                               ranges = <0 0x292e0000 0x10000>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               sec_jr0: jr@1000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x1000 0x1000>;
+                                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr1: jr@2000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x2000 0x1000>;
+                                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr2: jr@3000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x3000 0x1000>;
+                                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr3: jr@4000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x4000 0x1000>;
+                                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+
                        tpm5: tpm@29340000 {
                                compatible = "fsl,imx8ulp-tpm", "fsl,imx7ulp-tpm";
                                reg = <0x29340000 0x1000>;
                                status = "disabled";
                        };
 
+                       usbotg1: usb@29900000 {
+                               compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+                               reg = <0x29900000 0x200>;
+                               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&pcc4 IMX8ULP_CLK_USB0>;
+                               power-domains = <&scmi_devpd IMX8ULP_PD_USB0>;
+                               phys = <&usbphy1>;
+                               fsl,usbmisc = <&usbmisc1 0>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x8>;
+                               rx-burst-size-dword = <0x8>;
+                               status = "disabled";
+                       };
+
+                       usbmisc1: usbmisc@29900200 {
+                               compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+                                            "fsl,imx6q-usbmisc";
+                               reg = <0x29900200 0x200>;
+                               #index-cells = <1>;
+                               status = "disabled";
+                       };
+
+                       usbphy1: usb-phy@29910000 {
+                               compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+                               reg = <0x29910000 0x10000>;
+                               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&pcc4 IMX8ULP_CLK_USB0_PHY>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       usbotg2: usb@29920000 {
+                               compatible = "fsl,imx8ulp-usb", "fsl,imx7ulp-usb", "fsl,imx6ul-usb";
+                               reg = <0x29920000 0x200>;
+                               interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&pcc4 IMX8ULP_CLK_USB1>;
+                               power-domains = <&scmi_devpd IMX8ULP_PD_USDHC2_USB1>;
+                               phys = <&usbphy2>;
+                               fsl,usbmisc = <&usbmisc2 0>;
+                               ahb-burst-config = <0x0>;
+                               tx-burst-size-dword = <0x8>;
+                               rx-burst-size-dword = <0x8>;
+                               status = "disabled";
+                       };
+
+                       usbmisc2: usbmisc@29920200 {
+                               compatible = "fsl,imx8ulp-usbmisc", "fsl,imx7d-usbmisc",
+                                            "fsl,imx6q-usbmisc";
+                               reg = <0x29920200 0x200>;
+                               #index-cells = <1>;
+                               status = "disabled";
+                       };
+
+                       usbphy2: usb-phy@29930000 {
+                               compatible = "fsl,imx8ulp-usbphy", "fsl,imx7ulp-usbphy";
+                               reg = <0x29930000 0x10000>;
+                               interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&pcc4 IMX8ULP_CLK_USB1_PHY>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+
                        fec: ethernet@29950000 {
                                compatible = "fsl,imx8ulp-fec", "fsl,imx6ul-fec", "fsl,imx6q-fec";
                                reg = <0x29950000 0x10000>;
index 9921ea13ab4892eda6c9e046126af76debd5bb82..d400d85f42a92283518034fd4043f7cd92a1e40a 100644 (file)
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx93.dtsi"
 
 / {
@@ -38,7 +39,7 @@
                        no-map;
                };
 
-               vdev1vring0: vdev1vring0@a4000000 {
+               vdev1vring0: vdev1vring0@a4010000 {
                        reg = <0 0xa4010000 0 0x8000>;
                        no-map;
                };
@@ -48,8 +49,8 @@
                        no-map;
                };
 
-               rsc_table: rsc-table@2021f000 {
-                       reg = <0 0x2021f000 0 0x1000>;
+               rsc_table: rsc-table@2021e000 {
+                       reg = <0 0x2021e000 0 0x1000>;
                        no-map;
                };
 
        status = "okay";
 };
 
-&eqos {
+&lpi2c3 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <400000>;
        pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpi2c3>;
+       status = "okay";
+
+       ptn5110: tcpc@50 {
+               compatible = "nxp,ptn5110", "tcpci";
+               reg = <0x50>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+               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;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       typec1_dr_sw: endpoint {
+                                               remote-endpoint = <&usb1_drd_sw>;
+                                       };
+                               };
+                       };
+               };
+       };
+
+       ptn5110_2: tcpc@51 {
+               compatible = "nxp,ptn5110", "tcpci";
+               reg = <0x51>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+
+               typec2_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;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       typec2_dr_sw: endpoint {
+                                               remote-endpoint = <&usb2_drd_sw>;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&eqos {
+       pinctrl-names = "default", "sleep";
        pinctrl-0 = <&pinctrl_eqos>;
+       pinctrl-1 = <&pinctrl_eqos_sleep>;
        phy-mode = "rgmii-id";
        phy-handle = <&ethphy1>;
        status = "okay";
                ethphy1: ethernet-phy@1 {
                        reg = <1>;
                        eee-broken-1000t;
+                       reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <10000>;
+                       reset-deassert-us = <80000>;
                };
        };
 };
 
 &fec {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "sleep";
        pinctrl-0 = <&pinctrl_fec>;
+       pinctrl-1 = <&pinctrl_fec_sleep>;
        phy-mode = "rgmii-id";
        phy-handle = <&ethphy2>;
        fsl,magic-packet;
                ethphy2: ethernet-phy@2 {
                        reg = <2>;
                        eee-broken-1000t;
+                       reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <10000>;
+                       reset-deassert-us = <80000>;
                };
        };
 };
        status = "okay";
 };
 
+&usbotg1 {
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       usb-role-switch;
+       disable-over-current;
+       samsung,picophy-pre-emp-curr-control = <3>;
+       samsung,picophy-dc-vol-level-adjust = <7>;
+       status = "okay";
+
+       port {
+               usb1_drd_sw: endpoint {
+                       remote-endpoint = <&typec1_dr_sw>;
+               };
+       };
+};
+
+&usbotg2 {
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       usb-role-switch;
+       disable-over-current;
+       samsung,picophy-pre-emp-curr-control = <3>;
+       samsung,picophy-dc-vol-level-adjust = <7>;
+       status = "okay";
+
+       port {
+               usb2_drd_sw: endpoint {
+                       remote-endpoint = <&typec2_dr_sw>;
+               };
+       };
+};
+
 &usdhc1 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc1>;
-       pinctrl-1 = <&pinctrl_usdhc1>;
-       pinctrl-2 = <&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-names = "default", "state_100mhz", "state_200mhz", "sleep";
        pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
-       pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>;
        cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
        vmmc-supply = <&reg_usdhc2_vmmc>;
        bus-width = <4>;
        status = "okay";
 };
 
+&lpi2c2 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       clock-frequency = <400000>;
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&pinctrl_lpi2c2>;
+       pinctrl-1 = <&pinctrl_lpi2c2>;
+       status = "okay";
+
+       pcal6524: gpio@22 {
+               compatible = "nxp,pcal6524";
+               reg = <0x22>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pcal6524>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <27 IRQ_TYPE_LEVEL_LOW>;
+       };
+
+       pmic@25 {
+               compatible = "nxp,pca9451a";
+               reg = <0x25>;
+               interrupt-parent = <&pcal6524>;
+               interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+
+               regulators {
+                       buck1: BUCK1 {
+                               regulator-name = "BUCK1";
+                               regulator-min-microvolt = <610000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <3125>;
+                       };
+
+                       buck2: BUCK2 {
+                               regulator-name = "BUCK2";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <670000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <3125>;
+                       };
+
+                       buck4: BUCK4{
+                               regulator-name = "BUCK4";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <3400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck5: BUCK5{
+                               regulator-name = "BUCK5";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <3400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck6: BUCK6 {
+                               regulator-name = "BUCK6";
+                               regulator-min-microvolt = <1060000>;
+                               regulator-max-microvolt = <1140000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo1: LDO1 {
+                               regulator-name = "LDO1";
+                               regulator-min-microvolt = <1620000>;
+                               regulator-max-microvolt = <1980000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4: LDO4 {
+                               regulator-name = "LDO4";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <840000>;
+                               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;
+                       };
+               };
+       };
+};
+
+&lpi2c3 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpi2c3>;
+       status = "okay";
+
+       pcf2131: rtc@53 {
+               compatible = "nxp,pcf2131";
+               reg = <0x53>;
+               interrupt-parent = <&pcal6524>;
+               interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+       };
+};
+
 &iomuxc {
        pinctrl_eqos: eqosgrp {
                fsl,pins = <
                >;
        };
 
+       pinctrl_eqos_sleep: eqossleepgrp {
+               fsl,pins = <
+                       MX93_PAD_ENET1_MDC__GPIO4_IO00                          0x31e
+                       MX93_PAD_ENET1_MDIO__GPIO4_IO01                         0x31e
+                       MX93_PAD_ENET1_RD0__GPIO4_IO10                          0x31e
+                       MX93_PAD_ENET1_RD1__GPIO4_IO11                          0x31e
+                       MX93_PAD_ENET1_RD2__GPIO4_IO12                          0x31e
+                       MX93_PAD_ENET1_RD3__GPIO4_IO13                          0x31e
+                       MX93_PAD_ENET1_RXC__GPIO4_IO09                          0x31e
+                       MX93_PAD_ENET1_RX_CTL__GPIO4_IO08                       0x31e
+                       MX93_PAD_ENET1_TD0__GPIO4_IO05                          0x31e
+                       MX93_PAD_ENET1_TD1__GPIO4_IO04                          0x31e
+                       MX93_PAD_ENET1_TD2__GPIO4_IO03                          0x31e
+                       MX93_PAD_ENET1_TD3__GPIO4_IO02                          0x31e
+                       MX93_PAD_ENET1_TXC__GPIO4_IO07                          0x31e
+                       MX93_PAD_ENET1_TX_CTL__GPIO4_IO06                       0x31e
+               >;
+       };
+
        pinctrl_fec: fecgrp {
                fsl,pins = <
                        MX93_PAD_ENET2_MDC__ENET1_MDC                   0x57e
                >;
        };
 
+       pinctrl_lpi2c3: lpi2c3grp {
+               fsl,pins = <
+                       MX93_PAD_GPIO_IO28__LPI2C3_SDA                  0x40000b9e
+                       MX93_PAD_GPIO_IO29__LPI2C3_SCL                  0x40000b9e
+               >;
+       };
+
+       pinctrl_fec_sleep: fecsleepgrp {
+               fsl,pins = <
+                       MX93_PAD_ENET2_MDC__GPIO4_IO14                  0x51e
+                       MX93_PAD_ENET2_MDIO__GPIO4_IO15                 0x51e
+                       MX93_PAD_ENET2_RD0__GPIO4_IO24                  0x51e
+                       MX93_PAD_ENET2_RD1__GPIO4_IO25                  0x51e
+                       MX93_PAD_ENET2_RD2__GPIO4_IO26                  0x51e
+                       MX93_PAD_ENET2_RD3__GPIO4_IO27                  0x51e
+                       MX93_PAD_ENET2_RXC__GPIO4_IO23                  0x51e
+                       MX93_PAD_ENET2_RX_CTL__GPIO4_IO22               0x51e
+                       MX93_PAD_ENET2_TD0__GPIO4_IO19                  0x51e
+                       MX93_PAD_ENET2_TD1__GPIO4_IO18                  0x51e
+                       MX93_PAD_ENET2_TD2__GPIO4_IO17                  0x51e
+                       MX93_PAD_ENET2_TD3__GPIO4_IO16                  0x51e
+                       MX93_PAD_ENET2_TXC__GPIO4_IO21                  0x51e
+                       MX93_PAD_ENET2_TX_CTL__GPIO4_IO20               0x51e
+               >;
+       };
+
        pinctrl_uart1: uart1grp {
                fsl,pins = <
                        MX93_PAD_UART1_RXD__LPUART1_RX                  0x31e
                >;
        };
 
+       pinctrl_lpi2c2: lpi2c2grp {
+               fsl,pins = <
+                       MX93_PAD_I2C2_SCL__LPI2C2_SCL                   0x40000b9e
+                       MX93_PAD_I2C2_SDA__LPI2C2_SDA                   0x40000b9e
+               >;
+       };
+
+       pinctrl_lpi2c3: lpi2c3grp {
+               fsl,pins = <
+                       MX93_PAD_GPIO_IO28__LPI2C3_SDA                  0x40000b9e
+                       MX93_PAD_GPIO_IO29__LPI2C3_SCL                  0x40000b9e
+               >;
+       };
+
+       pinctrl_pcal6524: pcal6524grp {
+               fsl,pins = <
+                       MX93_PAD_CCM_CLKO2__GPIO3_IO27                  0x31e
+               >;
+       };
+
        /* need to config the SION for data and cmd pad, refer to ERR052021 */
        pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX93_PAD_SD1_CLK__USDHC1_CLK            0x1582
+                       MX93_PAD_SD1_CMD__USDHC1_CMD            0x40001382
+                       MX93_PAD_SD1_DATA0__USDHC1_DATA0        0x40001382
+                       MX93_PAD_SD1_DATA1__USDHC1_DATA1        0x40001382
+                       MX93_PAD_SD1_DATA2__USDHC1_DATA2        0x40001382
+                       MX93_PAD_SD1_DATA3__USDHC1_DATA3        0x40001382
+                       MX93_PAD_SD1_DATA4__USDHC1_DATA4        0x40001382
+                       MX93_PAD_SD1_DATA5__USDHC1_DATA5        0x40001382
+                       MX93_PAD_SD1_DATA6__USDHC1_DATA6        0x40001382
+                       MX93_PAD_SD1_DATA7__USDHC1_DATA7        0x40001382
+                       MX93_PAD_SD1_STROBE__USDHC1_STROBE      0x1582
+               >;
+       };
+
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+               fsl,pins = <
+                       MX93_PAD_SD1_CLK__USDHC1_CLK            0x158e
+                       MX93_PAD_SD1_CMD__USDHC1_CMD            0x4000138e
+                       MX93_PAD_SD1_DATA0__USDHC1_DATA0        0x4000138e
+                       MX93_PAD_SD1_DATA1__USDHC1_DATA1        0x4000138e
+                       MX93_PAD_SD1_DATA2__USDHC1_DATA2        0x4000138e
+                       MX93_PAD_SD1_DATA3__USDHC1_DATA3        0x4000138e
+                       MX93_PAD_SD1_DATA4__USDHC1_DATA4        0x4000138e
+                       MX93_PAD_SD1_DATA5__USDHC1_DATA5        0x4000138e
+                       MX93_PAD_SD1_DATA6__USDHC1_DATA6        0x4000138e
+                       MX93_PAD_SD1_DATA7__USDHC1_DATA7        0x4000138e
+                       MX93_PAD_SD1_STROBE__USDHC1_STROBE      0x158e
+               >;
+       };
+
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
                fsl,pins = <
                        MX93_PAD_SD1_CLK__USDHC1_CLK            0x15fe
                        MX93_PAD_SD1_CMD__USDHC1_CMD            0x400013fe
                >;
        };
 
+       pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp {
+               fsl,pins = <
+                       MX93_PAD_SD2_CD_B__GPIO3_IO00           0x51e
+               >;
+       };
+
        /* need to config the SION for data and cmd pad, refer to ERR052021 */
        pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX93_PAD_SD2_CLK__USDHC2_CLK            0x1582
+                       MX93_PAD_SD2_CMD__USDHC2_CMD            0x40001382
+                       MX93_PAD_SD2_DATA0__USDHC2_DATA0        0x40001382
+                       MX93_PAD_SD2_DATA1__USDHC2_DATA1        0x40001382
+                       MX93_PAD_SD2_DATA2__USDHC2_DATA2        0x40001382
+                       MX93_PAD_SD2_DATA3__USDHC2_DATA3        0x40001382
+                       MX93_PAD_SD2_VSELECT__USDHC2_VSELECT    0x51e
+               >;
+       };
+
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+               fsl,pins = <
+                       MX93_PAD_SD2_CLK__USDHC2_CLK            0x158e
+                       MX93_PAD_SD2_CMD__USDHC2_CMD            0x4000138e
+                       MX93_PAD_SD2_DATA0__USDHC2_DATA0        0x4000138e
+                       MX93_PAD_SD2_DATA1__USDHC2_DATA1        0x4000138e
+                       MX93_PAD_SD2_DATA2__USDHC2_DATA2        0x4000138e
+                       MX93_PAD_SD2_DATA3__USDHC2_DATA3        0x4000138e
+                       MX93_PAD_SD2_VSELECT__USDHC2_VSELECT    0x51e
+               >;
+       };
+
+       /* need to config the SION for data and cmd pad, refer to ERR052021 */
+       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
                fsl,pins = <
                        MX93_PAD_SD2_CLK__USDHC2_CLK            0x15fe
                        MX93_PAD_SD2_CMD__USDHC2_CMD            0x400013fe
                        MX93_PAD_SD2_VSELECT__USDHC2_VSELECT    0x51e
                >;
        };
+
+       pinctrl_usdhc2_sleep: usdhc2sleepgrp {
+               fsl,pins = <
+                       MX93_PAD_SD2_CLK__GPIO3_IO01            0x51e
+                       MX93_PAD_SD2_CMD__GPIO3_IO02            0x51e
+                       MX93_PAD_SD2_DATA0__GPIO3_IO03          0x51e
+                       MX93_PAD_SD2_DATA1__GPIO3_IO04          0x51e
+                       MX93_PAD_SD2_DATA2__GPIO3_IO05          0x51e
+                       MX93_PAD_SD2_DATA3__GPIO3_IO06          0x51e
+                       MX93_PAD_SD2_VSELECT__GPIO3_IO19        0x51e
+               >;
+       };
+
 };
index 601c94e1fac8ea222e1f59a48a1b1b6318eecfa4..4a3f42355cb8fcfcb75e60c5170495b858c25d24 100644 (file)
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx93-clock.h>
+#include <dt-bindings/dma/fsl-edma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
                status = "disabled";
        };
 
+       usbphynop1: usbphynop1 {
+               compatible = "usb-nop-xceiv";
+               #phy-cells = <0>;
+               clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+               clock-names = "main_clk";
+       };
+
+       usbphynop2: usbphynop2 {
+               compatible = "usb-nop-xceiv";
+               #phy-cells = <0>;
+               clocks = <&clk IMX93_CLK_USB_PHY_BURUNIN>;
+               clock-names = "main_clk";
+       };
+
        soc@0 {
                compatible = "simple-bus";
                #address-cells = <1>;
                                clocks = <&clk IMX93_CLK_LPI2C1_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma1 7 0 0>, <&edma1 8 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPI2C2_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma1 9 0 0>, <&edma1 10 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI1_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma1 11 0 0>, <&edma1 12 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI2_GATE>,
                                         <&clk IMX93_CLK_BUS_AON>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma1 13 0 0>, <&edma1 14 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART1_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma1 17 0 1>, <&edma1 16 0 0>;
+                               dmas = <&edma1 17 0 FSL_EDMA_RX>, <&edma1 16 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART2_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma1 19 0 1>, <&edma1 18 0 0>;
+                               dmas = <&edma1 19 0 FSL_EDMA_RX>, <&edma1 18 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                         <&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>,
                                         <&clk IMX93_CLK_DUMMY>;
                                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-                               dmas = <&edma1 22 0 1>, <&edma1 21 0 0>;
+                               dmas = <&edma1 22 0 FSL_EDMA_RX>, <&edma1 21 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                reg = <0x44530000 0x10000>;
                                interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
-                                            <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
-                                            <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+                                            <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_ADC1_GATE>;
                                clock-names = "ipg";
                                #io-channel-cells = <1>;
                                clocks = <&clk IMX93_CLK_LPI2C3_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 8 0 0>, <&edma2 9 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPI2C4_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 10 0 0>, <&edma2 11 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI3_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 12 0 0>, <&edma2 13 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI4_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 14 0 0>, <&edma2 15 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART3_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 18 0 1>, <&edma2 17 0 0>;
+                               dmas = <&edma2 18 0 FSL_EDMA_RX>, <&edma2 17 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART4_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 20 0 1>, <&edma2 19 0 0>;
+                               dmas = <&edma2 20 0 FSL_EDMA_RX>, <&edma2 19 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART5_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 22 0 1>, <&edma2 21 0 0>;
+                               dmas = <&edma2 22 0 FSL_EDMA_RX>, <&edma2 21 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART6_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 24 0 1>, <&edma2 23 0 0>;
+                               dmas = <&edma2 24 0 FSL_EDMA_RX>, <&edma2 23 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                         <&clk IMX93_CLK_SAI2_GATE>, <&clk IMX93_CLK_DUMMY>,
                                         <&clk IMX93_CLK_DUMMY>;
                                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-                               dmas = <&edma2 59 0 1>, <&edma2 58 0 0>;
+                               dmas = <&edma2 59 0 FSL_EDMA_RX>, <&edma2 58 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                         <&clk IMX93_CLK_SAI3_GATE>, <&clk IMX93_CLK_DUMMY>,
                                         <&clk IMX93_CLK_DUMMY>;
                                clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-                               dmas = <&edma2 61 0 1>, <&edma2 60 0 0>;
+                               dmas = <&edma2 61 0 FSL_EDMA_RX>, <&edma2 60 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                         <&clk IMX93_CLK_DUMMY>,
                                         <&clk IMX93_CLK_AUD_XCVR_GATE>;
                                clock-names = "ipg", "phy", "spba", "pll_ipg";
-                               dmas = <&edma2 65 0 1>, <&edma2 66 0 0>;
+                               dmas = <&edma2 65 0 FSL_EDMA_RX>, <&edma2 66 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART7_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 88 0 1>, <&edma2 87 0 0>;
+                               dmas = <&edma2 88 0 FSL_EDMA_RX>, <&edma2 87 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX93_CLK_LPUART8_GATE>;
                                clock-names = "ipg";
-                               dmas = <&edma2 90 0 1>, <&edma2 89 0 0>;
+                               dmas = <&edma2 90 0 FSL_EDMA_RX>, <&edma2 89 0 0>;
                                dma-names = "rx", "tx";
                                status = "disabled";
                        };
                                clocks = <&clk IMX93_CLK_LPI2C5_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 71 0 0>, <&edma2 72 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPI2C6_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 73 0 0>, <&edma2 74 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPI2C7_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 75 0 0>, <&edma2 76 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPI2C8_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 77 0 0>, <&edma2 78 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI5_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 79 0 0>, <&edma2 80 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI6_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 81 0 0>, <&edma2 82 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI7_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 83 0 0>, <&edma2 84 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                clocks = <&clk IMX93_CLK_LPSPI8_GATE>,
                                         <&clk IMX93_CLK_BUS_WAKEUP>;
                                clock-names = "per", "ipg";
+                               dmas = <&edma2 85 0 0>, <&edma2 86 0 FSL_EDMA_RX>;
+                               dma-names = "tx", "rx";
                                status = "disabled";
                        };
 
                                         <&clk IMX93_CLK_WAKEUP_AXI>,
                                         <&clk IMX93_CLK_USDHC1_GATE>;
                                clock-names = "ipg", "ahb", "per";
+                               assigned-clocks = <&clk IMX93_CLK_USDHC1>;
+                               assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+                               assigned-clock-rates = <400000000>;
                                bus-width = <8>;
                                fsl,tuning-start-tap = <1>;
                                fsl,tuning-step = <2>;
                                         <&clk IMX93_CLK_WAKEUP_AXI>,
                                         <&clk IMX93_CLK_USDHC2_GATE>;
                                clock-names = "ipg", "ahb", "per";
+                               assigned-clocks = <&clk IMX93_CLK_USDHC2>;
+                               assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+                               assigned-clock-rates = <400000000>;
                                bus-width = <4>;
                                fsl,tuning-start-tap = <1>;
                                fsl,tuning-step = <2>;
                                fsl,num-tx-queues = <3>;
                                fsl,num-rx-queues = <3>;
                                fsl,stop-mode = <&wakeupmix_gpr 0x0c 1>;
+                               nvmem-cells = <&eth_mac1>;
+                               nvmem-cell-names = "mac-address";
                                status = "disabled";
                        };
 
                                assigned-clock-rates = <100000000>, <250000000>;
                                intf_mode = <&wakeupmix_gpr 0x28>;
                                snps,clk-csr = <0>;
+                               nvmem-cells = <&eth_mac2>;
+                               nvmem-cell-names = "mac-address";
                                status = "disabled";
                        };
 
                                         <&clk IMX93_CLK_WAKEUP_AXI>,
                                         <&clk IMX93_CLK_USDHC3_GATE>;
                                clock-names = "ipg", "ahb", "per";
+                               assigned-clocks = <&clk IMX93_CLK_USDHC3>;
+                               assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1>;
+                               assigned-clock-rates = <400000000>;
                                bus-width = <4>;
                                fsl,tuning-start-tap = <1>;
                                fsl,tuning-step = <2>;
                        reg = <0x47510000 0x10000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
+
+                       eth_mac1: mac-address@4ec {
+                               reg = <0x4ec 0x6>;
+                       };
+
+                       eth_mac2: mac-address@4f2 {
+                               reg = <0x4f2 0x6>;
+                       };
+
                };
 
                s4muap: mailbox@47520000 {
                        status = "disabled";
                };
 
+               usbotg1: usb@4c100000 {
+                       compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+                       reg = <0x4c100000 0x200>;
+                       interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+                                <&clk IMX93_CLK_HSIO_32K_GATE>;
+                       clock-names = "usb_ctrl_root", "usb_wakeup";
+                       assigned-clocks = <&clk IMX93_CLK_HSIO>;
+                       assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+                       assigned-clock-rates = <133000000>;
+                       phys = <&usbphynop1>;
+                       fsl,usbmisc = <&usbmisc1 0>;
+                       status = "disabled";
+               };
+
+               usbmisc1: usbmisc@4c100200 {
+                       compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+                                    "fsl,imx6q-usbmisc";
+                       reg = <0x4c100200 0x200>;
+                       #index-cells = <1>;
+               };
+
+               usbotg2: usb@4c200000 {
+                       compatible = "fsl,imx93-usb", "fsl,imx7d-usb", "fsl,imx27-usb";
+                       reg = <0x4c200000 0x200>;
+                       interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk IMX93_CLK_USB_CONTROLLER_GATE>,
+                                <&clk IMX93_CLK_HSIO_32K_GATE>;
+                       clock-names = "usb_ctrl_root", "usb_wakeup";
+                       assigned-clocks = <&clk IMX93_CLK_HSIO>;
+                       assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD1_DIV2>;
+                       assigned-clock-rates = <133000000>;
+                       phys = <&usbphynop2>;
+                       fsl,usbmisc = <&usbmisc2 0>;
+                       status = "disabled";
+               };
+
+               usbmisc2: usbmisc@4c200200 {
+                       compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc",
+                                    "fsl,imx6q-usbmisc";
+                       reg = <0x4c200200 0x200>;
+                       #index-cells = <1>;
+               };
+
                ddr-pmu@4e300dc0 {
                        compatible = "fsl,imx93-ddr-pmu";
                        reg = <0x4e300dc0 0x200>;
index 427467df42bfa66ba5ed7eedd11be752d3820b18..815241526a0d3da100c465622c1cf90c02e5398f 100644 (file)
 &mipi_dsi {
        samsung,burst-clock-frequency = <891000000>;
        samsung,esc-clock-frequency = <20000000>;
+};
 
-       ports {
-               port@1 {
-                       reg = <1>;
-
-                       mipi_dsi_out: endpoint {
-                               data-lanes = <1 2 3 4>;
-                               remote-endpoint = <&lvds_bridge_in>;
-                       };
-               };
-       };
+&mipi_dsi_out {
+       data-lanes = <1 2 3 4>;
+       remote-endpoint = <&lvds_bridge_in>;
 };
 
 &pwm3 {
index 5ac1cc9ff50ed140a8e0c13456c05bd8310fef0e..fc19ae2e8d3bc4b2e40bc34bcbe402782f4e77ca 100644 (file)
@@ -3,7 +3,7 @@
  * NXP S32G2 SoC family
  *
  * Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2017-2021 NXP
+ * Copyright 2017-2021, 2024 NXP
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
        #address-cells = <2>;
        #size-cells = <2>;
 
+       reserved-memory  {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               scmi_buf: shm@d0000000 {
+                       compatible = "arm,scmi-shmem";
+                       reg = <0x0 0xd0000000 0x0 0x80>;
+                       no-map;
+               };
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
        };
 
        firmware {
+               scmi {
+                       compatible = "arm,scmi-smc";
+                       arm,smc-id = <0xc20000fe>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       shmem = <&scmi_buf>;
+
+                       clks: protocol@14 {
+                               reg = <0x14>;
+                               #clock-cells = <1>;
+                       };
+               };
+
                psci {
                        compatible = "arm,psci-1.0";
                        method = "smc";
                        status = "disabled";
                };
 
+               usdhc0: mmc@402f0000 {
+                       compatible = "nxp,s32g2-usdhc";
+                       reg = <0x402f0000 0x1000>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks 32>, <&clks 31>, <&clks 33>;
+                       clock-names = "ipg", "ahb", "per";
+                       bus-width = <8>;
+                       status = "disabled";
+               };
+
                gic: interrupt-controller@50800000 {
                        compatible = "arm,gic-v3";
                        reg = <0x50800000 0x10000>,
index 9118d8d2ee019babf2cf45c5c80710f7bba0037a..00070c949e2ab2b97ae310ecf660776a0a824cf9 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
  * Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2019-2021 NXP
+ * Copyright 2019-2021, 2024 NXP
  */
 
 /dts-v1/;
@@ -32,3 +32,7 @@
 &uart0 {
        status = "okay";
 };
+
+&usdhc0 {
+       status = "okay";
+};
index e05ee854cdf5e39854a41ffd8677cdda9b58c7be..b3fc12899cae52971da507f4a71e5fe33116210a 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 /*
  * Copyright (c) 2021 SUSE LLC
- * Copyright (c) 2019-2021 NXP
+ * Copyright 2019-2021, 2024 NXP
  */
 
 /dts-v1/;
@@ -38,3 +38,7 @@
 &uart1 {
        status = "okay";
 };
+
+&usdhc0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi
new file mode 100644 (file)
index 0000000..c1b0899
--- /dev/null
@@ -0,0 +1,233 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2021-2023 NXP
+ *
+ * Authors: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
+ *          Ciprian Costea <ciprianmarian.costea@nxp.com>
+ *          Andra-Teodora Ilie <andra.ilie@nxp.com>
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+       compatible = "nxp,s32g3";
+       interrupt-parent = <&gic>;
+       #address-cells = <0x02>;
+       #size-cells = <0x02>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+
+                               core2 {
+                                       cpu = <&cpu2>;
+                               };
+
+                               core3 {
+                                       cpu = <&cpu3>;
+                               };
+                       };
+
+                       cluster1 {
+                               core0 {
+                                       cpu = <&cpu4>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu5>;
+                               };
+
+                               core2 {
+                                       cpu = <&cpu6>;
+                               };
+
+                               core3 {
+                                       cpu = <&cpu7>;
+                               };
+                       };
+               };
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x1>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x2>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x3>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu4: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x100>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu5: cpu@101 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x101>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu6: cpu@102 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x102>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+
+               cpu7: cpu@103 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x103>;
+                       enable-method = "psci";
+                       clocks = <&dfs 0>;
+               };
+       };
+
+       firmware {
+               scmi: scmi {
+                       compatible = "arm,scmi-smc";
+                       shmem = <&scmi_shmem>;
+                       arm,smc-id = <0xc20000fe>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       dfs: protocol@13 {
+                               reg = <0x13>;
+                               #clock-cells = <1>;
+                       };
+
+                       clks: protocol@14 {
+                               reg = <0x14>;
+                               #clock-cells = <1>;
+                       };
+               };
+
+               psci: psci {
+                       compatible = "arm,psci-1.0";
+                       method = "smc";
+               };
+       };
+
+
+       pmu {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       reserved-memory  {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               scmi_shmem: shm@d0000000 {
+                       compatible = "arm,scmi-shmem";
+                       reg = <0x0 0xd0000000 0x0 0x80>;
+                       no-map;
+               };
+       };
+
+       soc@0 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0 0x80000000>;
+
+               uart0: serial@401c8000 {
+                       compatible = "nxp,s32g3-linflexuart",
+                                    "fsl,s32v234-linflexuart";
+                       reg = <0x401c8000 0x3000>;
+                       interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+               };
+
+               uart1: serial@401cc000 {
+                       compatible = "nxp,s32g3-linflexuart",
+                                    "fsl,s32v234-linflexuart";
+                       reg = <0x401cc000 0x3000>;
+                       interrupts = <GIC_SPI 83 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+               };
+
+               uart2: serial@402bc000 {
+                       compatible = "nxp,s32g3-linflexuart",
+                                    "fsl,s32v234-linflexuart";
+                       reg = <0x402bc000 0x3000>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+               };
+
+               usdhc0: mmc@402f0000 {
+                       compatible = "nxp,s32g3-usdhc",
+                                    "nxp,s32g2-usdhc";
+                       reg = <0x402f0000 0x1000>;
+                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clks 32>,
+                                <&clks 31>,
+                                <&clks 33>;
+                       clock-names = "ipg", "ahb", "per";
+                       status = "disabled";
+               };
+
+               gic: interrupt-controller@50800000 {
+                       compatible = "arm,gic-v3";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x50800000 0x10000>,
+                             <0x50900000 0x200000>,
+                             <0x50400000 0x2000>,
+                             <0x50410000 0x2000>,
+                             <0x50420000 0x2000>;
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* sec-phys */
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* phys */
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* virt */
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>, /* hyp-phys */
+                            <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>; /* hyp-virt */
+               arm,no-tick-in-suspend;
+       };
+};
diff --git a/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts b/arch/arm64/boot/dts/freescale/s32g399a-rdb3.dts
new file mode 100644 (file)
index 0000000..9d67481
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright 2021-2023 NXP
+ *
+ * NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)
+ */
+
+/dts-v1/;
+
+#include "s32g3.dtsi"
+
+/ {
+       model = "NXP S32G3 Reference Design Board 3 (S32G-VNP-RDB3)";
+       compatible = "nxp,s32g399a-rdb3", "nxp,s32g3";
+
+       aliases {
+               mmc0 = &usdhc0;
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       /* 4GiB RAM */
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0 0x80000000>,
+                     <0x8 0x80000000 0 0x80000000>;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&usdhc0 {
+       bus-width = <8>;
+       status = "okay";
+};
index ed1b5a7a606786f05214e6eadde077069b5cb903..f6bc001c3832632bf2262286daedd84238ba59af 100644 (file)
                        device_type = "cpu";
                        reg = <0x0 0x0>;
                        enable-method = "psci";
+                       d-cache-size = <0x8000>; /* 32 KiB */
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       i-cache-size = <0x8000>; /* 32 KiB */
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       next-level-cache = <&L2>;
                };
 
                cpu@1 {
                        device_type = "cpu";
                        reg = <0x0 0x1>;
                        enable-method = "psci";
+                       d-cache-size = <0x8000>; /* 32 KiB */
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       i-cache-size = <0x8000>; /* 32 KiB */
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       next-level-cache = <&L2>;
                };
 
                cpu@2 {
                        device_type = "cpu";
                        reg = <0x0 0x2>;
                        enable-method = "psci";
+                       d-cache-size = <0x8000>; /* 32 KiB */
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       i-cache-size = <0x8000>; /* 32 KiB */
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       next-level-cache = <&L2>;
                };
 
                cpu@3 {
                        device_type = "cpu";
                        reg = <0x0 0x3>;
                        enable-method = "psci";
+                       d-cache-size = <0x8000>; /* 32 KiB */
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       i-cache-size = <0x8000>; /* 32 KiB */
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       next-level-cache = <&L2>;
                };
        };
 
+       L2: l2-cache {
+               compatible = "cache";
+               cache-unified;
+               cache-size = <0x80000>; /* 512 KiB */
+               cache-line-size = <64>;
+               cache-sets = <512>;
+               cache-level = <2>;
+       };
+
        gic: interrupt-controller@f1001000 {
                compatible = "arm,gic-400";
                reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-                     <0x0 0xf1002000 0x0 0x100>;   /* GICC */
+                     <0x0 0xf1002000 0x0 0x2000>,  /* GICC */
+                     <0x0 0xf1004000 0x0 0x2000>,  /* GICH */
+                     <0x0 0xf1006000 0x0 0x2000>;  /* GICV */
+               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) |
+                             IRQ_TYPE_LEVEL_HIGH)>;
                #address-cells = <0>;
                #interrupt-cells = <3>;
                interrupt-controller;
index f0672ec65b26e1b7abec4d96d1faf1edbeef7ec6..2d304efe081de408329507d779d91e5f2f962931 100644 (file)
@@ -82,7 +82,7 @@
                };
        };
 
-       reg_sys_5v: regulator@0 {
+       reg_sys_5v: regulator-0 {
                compatible = "regulator-fixed";
                regulator-name = "SYS_5V";
                regulator-min-microvolt = <5000000>;
@@ -91,7 +91,7 @@
                regulator-always-on;
        };
 
-       reg_vdd_3v3: regulator@1 {
+       reg_vdd_3v3: regulator-1 {
                compatible = "regulator-fixed";
                regulator-name = "VDD_3V3";
                regulator-min-microvolt = <3300000>;
                vin-supply = <&reg_sys_5v>;
        };
 
-       reg_5v_hub: regulator@2 {
+       reg_5v_hub: regulator-2 {
                compatible = "regulator-fixed";
                regulator-name = "5V_HUB";
                regulator-min-microvolt = <5000000>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        port@0 {
+                               reg = <0>;
                                adv7533_in: endpoint {
                                        remote-endpoint = <&dsi_out0>;
                                };
index be808bb2544e6f24eab9e7a4ed40169fd83c7e47..a589954c29e2d9fb21903732b9d8b0768627e6ce 100644 (file)
                        clock-names = "wdog_clk", "apb_pclk";
                };
 
-               tsensor: tsensor@0,f7030700 {
+               tsensor: tsensor@f7030700 {
                        compatible = "hisilicon,tsensor";
                        reg = <0x0 0xf7030700 0x0 0x1000>;
                        interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
index c4eaebbb448f5c6bf55e2d8a3e33b208a45eebe4..b7792d4431894d07e7770b49ed276c6fec9f875e 100644 (file)
@@ -54,7 +54,7 @@
        ranges = <0 0 0x0 0x90000000 0x08000000>,
                 <1 0 0x0 0x98000000 0x08000000>;
 
-       nor-flash@0,0 {
+       nor-flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "numonyx,js28f00a", "cfi-flash";
@@ -75,7 +75,7 @@
                };
        };
 
-       cpld@1,0 {
+       cpld@100000000 {
                compatible = "hisilicon,hip05-cpld";
                reg = <1 0x0 0x100>;
        };
index 65ddc0698f8285d203a8620b769d4704811fd6e0..d0912ca5f237f1bcd695d1ee7402bb089e6f51d0 100644 (file)
                };
        };
 
+       refclk200mhz: refclk200mhz {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <200000000>;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
                #size-cells = <2>;
                ranges;
 
-               refclk200mhz: refclk200mhz {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-                       clock-frequency = <200000000>;
-               };
-
                uart0: serial@80300000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x0 0x80300000 0x0 0x10000>;
index f46c33d107507836ad85fe3a7dede7b52dc199dd..3d7285e6700e72479090ecfd6259ab15eb37e2f2 100644 (file)
                };
        };
 
+       eth2: ethernet-0 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <0>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth3: ethernet-1 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <1>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth0: ethernet-4 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <4>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth1: ethernet-5 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <5>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       refclk: refclk {
+               compatible = "fixed-clock";
+               clock-frequency = <50000000>;
+               #clock-cells = <0>;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
                        };
                };
 
-               refclk: refclk {
-                       compatible = "fixed-clock";
-                       clock-frequency = <50000000>;
-                       #clock-cells = <0>;
-               };
-
                usb_ohci: usb@a7030000 {
                        compatible = "generic-ohci";
                        reg = <0x0 0xa7030000 0x0 0x10000>;
                        };
                };
 
-               dsaf0: dsa@c7000000 {
+               dsaf0: dsa@c5000000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "hisilicon,hns-dsaf-v2";
                        };
                };
 
-               eth0: ethernet-4 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <4>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth1: ethernet-5 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <5>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth2: ethernet-0 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <0>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth3: ethernet-1 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <1>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
                sas0: sas@c3000000 {
                        compatible = "hisilicon,hip06-sas-v2";
                        reg = <0 0xc3000000 0 0x10000>;
                        status = "disabled";
                };
 
-               pcie0: pcie@a0090000 {
+               pcie0: pcie@b0000000 {
                        compatible = "hisilicon,hip06-pcie-ecam";
                        reg = <0 0xb0000000 0 0x2000000>,
                              <0 0xa0090000 0 0x10000>;
index 81d907ef43ed2d3ee5975d5fc79e68bc019f631b..00a6bfa7478cb459eb7441134fb54c039f234dd8 100644 (file)
                };
        };
 
+       eth0: ethernet-0 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <4>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth1: ethernet-1 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <5>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth2: ethernet-2 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <0>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
+       eth3: ethernet-3 {
+               compatible = "hisilicon,hns-nic-v2";
+               ae-handle = <&dsaf0>;
+               port-idx-in-ae = <1>;
+               local-mac-address = [00 00 00 00 00 00];
+               status = "disabled";
+               dma-coherent;
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
                        };
                };
 
-               dsaf0: dsa@c7000000 {
+               dsaf0: dsa@c5000000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        compatible = "hisilicon,hns-dsaf-v2";
                        };
                };
 
-               eth0: ethernet@4 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <4>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth1: ethernet@5 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <5>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth2: ethernet@0 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <0>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
-               eth3: ethernet@1 {
-                       compatible = "hisilicon,hns-nic-v2";
-                       ae-handle = <&dsaf0>;
-                       port-idx-in-ae = <1>;
-                       local-mac-address = [00 00 00 00 00 00];
-                       status = "disabled";
-                       dma-coherent;
-               };
-
                infiniband@c4000000 {
                        compatible = "hisilicon,hns-roce-v1";
                        reg = <0x0 0xc4000000 0x0 0x100000>;
                        status = "disabled";
                };
 
-               p0_pcie2_a: pcie@a00a0000 {
+               p0_pcie2_a: pcie@af800000 {
                        compatible = "hisilicon,hip07-pcie-ecam";
                        reg = <0 0xaf800000 0 0x800000>,
                              <0 0xa00a0000 0 0x10000>;
                                         0x0 0 0 4 &mbigen_pcie2_a 671 4>;
                        status = "disabled";
                };
-               p0_sec_a: crypto@d2000000 {
+               p0_sec_a: crypto@d0000000 {
                        compatible = "hisilicon,hip07-sec";
                        reg = <0x0 0xd0000000 0x0 0x10000>,
                              <0x0 0xd2000000 0x0 0x10000>,
                                     <605 1>, <606 4>,
                                     <607 1>, <608 4>;
                };
-               p0_sec_b: crypto@8,d2000000 {
+               p0_sec_b: crypto@8d0000000 {
                        compatible = "hisilicon,hip07-sec";
                        reg = <0x8 0xd0000000 0x0 0x10000>,
                              <0x8 0xd2000000 0x0 0x10000>,
                                     <605 1>, <606 4>,
                                     <607 1>, <608 4>;
                };
-               p1_sec_a: crypto@400,d2000000 {
+               p1_sec_a: crypto@400d0000000 {
                        compatible = "hisilicon,hip07-sec";
                        reg = <0x400 0xd0000000 0x0 0x10000>,
                              <0x400 0xd2000000 0x0 0x10000>,
                                     <605 1>, <606 4>,
                                     <607 1>, <608 4>;
                };
-               p1_sec_b: crypto@408,d2000000 {
+               p1_sec_b: crypto@408d0000000 {
                        compatible = "hisilicon,hip07-sec";
                        reg = <0x408 0xd0000000 0x0 0x10000>,
                              <0x408 0xd2000000 0x0 0x10000>,
index 781761d2942b1b0804a8978458eea5f6e2391b1e..ae00e9e54e82cbb99ad79c126a76ac51534443c1 100644 (file)
@@ -70,7 +70,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_PPI 0x7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index 76aafa172eb013ff22e601f1fcc9f1b07d960110..2a5eeb21da474fd01d4a22da06b2c0e78dac5221 100644 (file)
@@ -80,7 +80,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
index 260a2c5b19e50812122f0efef90023b10cf472d8..cdd10f1380986686d9a023b40648a6883a27f13d 100644 (file)
@@ -22,7 +22,7 @@
                serial2 = &uart2;
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x00000000 0x20000000>;
        };
index e89ae853788a2ee23efc362bd2d618be19b4781e..6ace977ff4cff0e5629ab7d100780e0a7ef6f2e6 100644 (file)
@@ -22,7 +22,7 @@
                serial2 = &uart2;
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x00000000 0x20000000>;
        };
index 5591939e057b8bd1d628223f20e986fe2f3df237..75377c292bcb6a57ea12215a9f4439c600942161 100644 (file)
@@ -68,7 +68,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a55-pmu";
                interrupts = <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index d6d37a1f6f3800fefe071a092aa2dd598894245d..91c2f8b4edfae369428c37aead072f3122cae9a1 100644 (file)
@@ -25,8 +25,6 @@
        /* Actual device is MV88E6361 */
        switch: switch@0 {
                compatible = "marvell,mv88e6190";
-               #address-cells = <1>;
-               #size-cells = <0>;
                reg = <0>;
                status = "disabled";
 
index 870bb380a40a67482586268eeac2e29a03f05abd..b3cc2b7b5d192351ef8500c67c1d8c3514d842a2 100644 (file)
 };
 
 &mdio {
+       /* Switch is @3, not @1 */
+       /delete-node/ ethernet-switch@1;
        extphy: ethernet-phy@1 {
                reg = <1>;
 
                reset-gpios = <&gpionb 2 GPIO_ACTIVE_LOW>;
        };
-};
 
-&switch0 {
-       reg = <3>;
+       switch0: ethernet-switch@3 {
+               compatible = "marvell,mv88e6085";
+               reg = <3>;
 
-       reset-gpios = <&gpiosb 23 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&gpiosb 23 GPIO_ACTIVE_LOW>;
+               dsa,member = <0 0>;
 
-       ethernet-ports {
-               switch0port1: ethernet-port@1 {
-                       reg = <1>;
-                       label = "lan0";
-                       phy-handle = <&switch0phy0>;
-               };
+               ethernet-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0port0: ethernet-port@0 {
+                               reg = <0>;
+                               label = "cpu";
+                               ethernet = <&eth0>;
+                               phy-mode = "rgmii-id";
+                               fixed-link {
+                                       speed = <1000>;
+                                       full-duplex;
+                               };
+                       };
 
-               switch0port2: ethernet-port@2 {
-                       reg = <2>;
-                       label = "lan1";
-                       phy-handle = <&switch0phy1>;
-               };
+                       switch0port1: ethernet-port@1 {
+                               reg = <1>;
+                               label = "lan0";
+                               phy-handle = <&switch0phy0>;
+                       };
 
-               switch0port3: ethernet-port@3 {
-                       reg = <3>;
-                       label = "lan2";
-                       phy-handle = <&switch0phy2>;
-               };
+                       switch0port2: ethernet-port@2 {
+                               reg = <2>;
+                               label = "lan1";
+                               phy-handle = <&switch0phy1>;
+                       };
 
-               switch0port4: ethernet-port@4 {
-                       reg = <4>;
-                       label = "lan3";
-                       phy-handle = <&switch0phy3>;
-               };
+                       switch0port3: ethernet-port@3 {
+                               reg = <3>;
+                               label = "lan2";
+                               phy-handle = <&switch0phy2>;
+                       };
 
-               switch0port5: ethernet-port@5 {
-                       reg = <5>;
-                       label = "wan";
-                       phy-handle = <&extphy>;
-                       phy-mode = "sgmii";
+                       switch0port4: ethernet-port@4 {
+                               reg = <4>;
+                               label = "lan3";
+                               phy-handle = <&switch0phy3>;
+                       };
+
+                       switch0port5: ethernet-port@5 {
+                               reg = <5>;
+                               label = "wan";
+                               phy-handle = <&extphy>;
+                               phy-mode = "sgmii";
+                       };
                };
-       };
 
-       mdio {
-               switch0phy3: ethernet-phy@14 {
-                       reg = <0x14>;
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0phy0: ethernet-phy@11 {
+                               reg = <0x11>;
+                       };
+                       switch0phy1: ethernet-phy@12 {
+                               reg = <0x12>;
+                       };
+                       switch0phy2: ethernet-phy@13 {
+                               reg = <0x13>;
+                       };
+                       switch0phy3: ethernet-phy@14 {
+                               reg = <0x14>;
+                       };
                };
        };
 };
index f1a9f223435919f05bcfaea45f73321aec313be9..54453b0a91f9697f563f5a59f229f3491b608327 100644 (file)
        assigned-clock-rates = <20000000>;
 
        flash@0 {
-               #address-cells = <1>;
-               #size-cells = <1>;
                compatible = "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <20000000>;
index 1cc3fa1c354de81ca9f6eaa4257b9b561a0deb2a..9603223dd761f1a5c84ee8aeaf29d5461094fa58 100644 (file)
@@ -68,7 +68,7 @@
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index 7ec7c789d87eff436c4f7362e417c71e2033a5b1..fdf88cd0eb029107927c35a59b4b23862d460466 100644 (file)
@@ -61,7 +61,7 @@
                        compatible = "simple-bus";
                        ranges = <0x0 0x0 0xf0000000 0x1000000>;
 
-                       smmu: iommu@5000000 {
+                       smmu: iommu@100000 {
                                compatible = "marvell,ap806-smmu-500", "arm,mmu-500";
                                reg = <0x100000 0x100000>;
                                dma-coherent;
index 6fcc34f7b46474545404641c6a775f7dbeca3b82..5e7d6de3cdded6b23315a2fdd351813b98a2bb08 100644 (file)
@@ -26,7 +26,7 @@
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
-       ap0_reg_mmc_vccq: ap0_mmc_vccq@0 {
+       ap0_reg_mmc_vccq: regulator-1 {
                compatible = "regulator-gpio";
                regulator-name = "ap0_mmc_vccq";
                regulator-min-microvolt = <1800000>;
@@ -36,7 +36,7 @@
                          3300000 0x0>;
        };
 
-       cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 {
+       cp0_reg_usb3_vbus1: regulator-2 {
                compatible = "regulator-fixed";
                regulator-name = "cp0-xhci1-vbus";
                regulator-min-microvolt = <5000000>;
                gpio = <&expander0 8 GPIO_ACTIVE_HIGH>;
        };
 
-       cp0_usb3_0_phy0: cp0_usb3_phy0 {
+       cp0_usb3_0_phy0: usb-phy-1 {
                compatible = "usb-nop-xceiv";
        };
 
-       cp0_usb3_0_phy1: cp0_usb3_phy1 {
+       cp0_usb3_0_phy1: usb-phy-2 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp0_reg_usb3_vbus1>;
        };
 
-       cp0_reg_sd_vccq: cp0_sd_vccq@0 {
+       cp0_reg_sd_vccq: regulator-3 {
                compatible = "regulator-gpio";
                regulator-name = "cp0_sd_vccq";
                regulator-min-microvolt = <1800000>;
@@ -64,7 +64,7 @@
                          3300000 0x0>;
        };
 
-       cp0_reg_sd_vcc: cp0_sd_vcc@0 {
+       cp0_reg_sd_vcc: regulator-4 {
                compatible = "regulator-fixed";
                regulator-name = "cp0_sd_vcc";
                regulator-min-microvolt = <3300000>;
@@ -82,7 +82,6 @@
                tx-disable-gpios = <&expander0 2 GPIO_ACTIVE_HIGH>;
                tx-fault-gpios = <&cp0_gpio1 24 GPIO_ACTIVE_HIGH>;
                maximum-power-milliwatt = <3000>;
-               status = "okay";
        };
 };
 
index 6eb6a175de38d550633f75d05093f1486d4ac20f..be56a233626534bd64e6f75a5a0821044c38caed 100644 (file)
@@ -30,7 +30,7 @@
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
-       ap0_reg_sd_vccq: ap0_sd_vccq@0 {
+       ap0_reg_sd_vccq: regulator-1 {
                compatible = "regulator-gpio";
                regulator-name = "ap0_sd_vccq";
                regulator-min-microvolt = <1800000>;
@@ -39,7 +39,7 @@
                states = <1800000 0x1 3300000 0x0>;
        };
 
-       cp0_reg_usb3_vbus0: cp0_usb3_vbus@0 {
+       cp0_reg_usb3_vbus0: regulator-2 {
                compatible = "regulator-fixed";
                regulator-name = "cp0-xhci0-vbus";
                regulator-min-microvolt = <5000000>;
                gpio = <&expander0 0 GPIO_ACTIVE_HIGH>;
        };
 
-       cp0_usb3_0_phy0: cp0_usb3_phy@0 {
+       cp0_usb3_0_phy0: usb-phy-1 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp0_reg_usb3_vbus0>;
        };
 
-       cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 {
+       cp0_reg_usb3_vbus1: regulator-3 {
                compatible = "regulator-fixed";
                regulator-name = "cp0-xhci1-vbus";
                regulator-min-microvolt = <5000000>;
                gpio = <&expander0 1 GPIO_ACTIVE_HIGH>;
        };
 
-       cp0_usb3_0_phy1: cp0_usb3_phy@1 {
+       cp0_usb3_0_phy1: usb-phy-2 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp0_reg_usb3_vbus1>;
        };
 
-       cp0_reg_sd_vccq: cp0_sd_vccq@0 {
+       cp0_reg_sd_vccq: regulator-4 {
                compatible = "regulator-gpio";
                regulator-name = "cp0_sd_vccq";
                regulator-min-microvolt = <1800000>;
@@ -77,7 +77,7 @@
                          3300000 0x0>;
        };
 
-       cp0_reg_sd_vcc: cp0_sd_vcc@0 {
+       cp0_reg_sd_vcc: regulator-5 {
                compatible = "regulator-fixed";
                regulator-name = "cp0_sd_vcc";
                regulator-min-microvolt = <3300000>;
@@ -87,7 +87,7 @@
                regulator-always-on;
        };
 
-       cp0_sfp_eth0: sfp-eth@0 {
+       cp0_sfp_eth0: sfp-eth-1 {
                compatible = "sff,sfp";
                i2c-bus = <&cp0_sfpp0_i2c>;
                los-gpios = <&cp0_module_expander1 11 GPIO_ACTIVE_HIGH>;
        reg = <0x700680 0x50>;
 
        flash@0 {
-               #address-cells = <0x1>;
-               #size-cells = <0x1>;
                compatible = "jedec,spi-nor";
                reg = <0x0>;
                /* On-board MUX does not allow higher frequencies */
index ff8422fae31b543542a379e96b54fd1238ea181e..ad7360c830486bf30854e5885e0d95c1b4260169 100644 (file)
@@ -18,7 +18,7 @@
                ethernet4 = &cp1_eth1;
        };
 
-       cp1_reg_usb3_vbus0: cp1_usb3_vbus@0 {
+       cp1_reg_usb3_vbus0: regulator-6 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&cp1_xhci0_vbus_pins>;
                gpio = <&cp1_gpio1 3 GPIO_ACTIVE_HIGH>;
        };
 
-       cp1_usb3_0_phy0: cp1_usb3_phy0 {
+       cp1_usb3_0_phy0: usb-phy-3 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp1_reg_usb3_vbus0>;
        };
 
-       cp1_sfp_eth1: sfp-eth1 {
+       cp1_sfp_eth1: sfp-eth-2 {
                compatible = "sff,sfp";
                i2c-bus = <&cp1_i2c0>;
                los-gpios = <&cp1_gpio1 11 GPIO_ACTIVE_HIGH>;
        reg = <0x700680 0x50>;
 
        flash@0 {
-               #address-cells = <0x1>;
-               #size-cells = <0x1>;
                compatible = "jedec,spi-nor";
                reg = <0x0>;
                /* On-board MUX does not allow higher frequencies */
index 512a4fa2861e792129997da9dddcd1c3cce9834f..e753cfdac697330512f6c46c2b656dd57768b2c5 100644 (file)
@@ -17,7 +17,7 @@
                ethernet5 = &cp2_eth0;
        };
 
-       cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 {
+       cp2_reg_usb3_vbus0: regulator-7 {
                compatible = "regulator-fixed";
                regulator-name = "cp2-xhci0-vbus";
                regulator-min-microvolt = <5000000>;
                gpio = <&cp2_gpio1 2 GPIO_ACTIVE_HIGH>;
        };
 
-       cp2_usb3_0_phy0: cp2_usb3_phy0 {
+       cp2_usb3_0_phy0: usb-phy-4 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp2_reg_usb3_vbus0>;
        };
 
-       cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 {
+       cp2_reg_usb3_vbus1: regulator-8 {
                compatible = "regulator-fixed";
                regulator-name = "cp2-xhci1-vbus";
                regulator-min-microvolt = <5000000>;
                gpio = <&cp2_gpio1 3 GPIO_ACTIVE_HIGH>;
        };
 
-       cp2_usb3_0_phy1: cp2_usb3_phy1 {
+       cp2_usb3_0_phy1: usb-phy-5 {
                compatible = "usb-nop-xceiv";
                vcc-supply = <&cp2_reg_usb3_vbus1>;
        };
 
-       cp2_reg_sd_vccq: cp2_sd_vccq@0 {
+       cp2_reg_sd_vccq: regulator-9 {
                compatible = "regulator-gpio";
                regulator-name = "cp2_sd_vcc";
                regulator-min-microvolt = <1800000>;
@@ -54,7 +54,7 @@
                states = <1800000 0x1 3300000 0x0>;
        };
 
-       cp2_sfp_eth0: sfp-eth0 {
+       cp2_sfp_eth0: sfp-eth-3 {
                compatible = "sff,sfp";
                i2c-bus = <&cp2_sfpp0_i2c>;
                los-gpios = <&cp2_module_expander1 11 GPIO_ACTIVE_HIGH>;
index a2e74b8293206467eadec0b8d1da1407e5046a13..6a7ae616512d620637a084698669fa64b486debe 100644 (file)
@@ -82,7 +82,8 @@
 };
 
 &mmc1 {
-       bt_reset: bt-reset {
+       bluetooth@2 {
+               reg = <2>;
                compatible = "mediatek,mt7921s-bluetooth";
                pinctrl-names = "default";
                pinctrl-0 = <&bt_pins_reset>;
index 9cbd6dd8f671aa1c7056314481f776cb00c2b3fe..d0b03dc4d3f43aca71683a3d9b33a409b8ce237f 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a35-pmu";
                interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_LOW>,
                             <GIC_SPI 5 IRQ_TYPE_LEVEL_LOW>,
                             <GIC_SPI 6 IRQ_TYPE_LEVEL_LOW>,
index 24075cd9142050025e222150dea4ef83e778a255..c3029e0abacc05a0aa8b30d4b65b45f2bfb277cd 100644 (file)
                        pinctrl-names = "default";
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       reg = <0x6 0x110102d4 0x24>;
+                       reg = <0x6 0x110102f8 0x24>;
                };
 
                mdio3: mdio@61101031c {
                        reg = <0x6 0x1101031c 0x24>;
                };
 
-               serdes: serdes@10808000 {
+               serdes: serdes@610808000 {
                        compatible = "microchip,sparx5-serdes";
                        #phy-cells = <1>;
                        clocks = <&sys_clk>;
index f3e226de5e5e913025146efcdef60a4c5c2093ef..2c5574734c9e3261029c7d1782dd890b7f7cc308 100644 (file)
 
        leds {
                compatible = "gpio-leds";
-               led@0 {
+               led-0 {
                        label = "twr0:green";
                        gpios = <&sgpio_out0 8 0 GPIO_ACTIVE_LOW>;
                };
-               led@1 {
+               led-1 {
                        label = "twr0:yellow";
                        gpios = <&sgpio_out0 8 1 GPIO_ACTIVE_LOW>;
                };
-               led@2 {
+               led-2 {
                        label = "twr1:green";
                        gpios = <&sgpio_out0 9 0 GPIO_ACTIVE_LOW>;
                };
-               led@3 {
+               led-3 {
                        label = "twr1:yellow";
                        gpios = <&sgpio_out0 9 1 GPIO_ACTIVE_LOW>;
                };
-               led@4 {
+               led-4 {
                        label = "twr2:green";
                        gpios = <&sgpio_out0 10 0 GPIO_ACTIVE_LOW>;
                };
-               led@5 {
+               led-5 {
                        label = "twr2:yellow";
                        gpios = <&sgpio_out0 10 1 GPIO_ACTIVE_LOW>;
                };
-               led@6 {
+               led-6 {
                        label = "twr3:green";
                        gpios = <&sgpio_out0 11 0 GPIO_ACTIVE_LOW>;
                };
-               led@7 {
+               led-7 {
                        label = "twr3:yellow";
                        gpios = <&sgpio_out0 11 1 GPIO_ACTIVE_LOW>;
                };
-               led@8 {
+               led-8 {
                        label = "eth12:green";
                        gpios = <&sgpio_out0 12 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@9 {
+               led-9 {
                        label = "eth12:yellow";
                        gpios = <&sgpio_out0 12 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@10 {
+               led-10 {
                        label = "eth13:green";
                        gpios = <&sgpio_out0 13 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@11 {
+               led-11 {
                        label = "eth13:yellow";
                        gpios = <&sgpio_out0 13 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@12 {
+               led-12 {
                        label = "eth14:green";
                        gpios = <&sgpio_out0 14 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@13 {
+               led-13 {
                        label = "eth14:yellow";
                        gpios = <&sgpio_out0 14 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@14 {
+               led-14 {
                        label = "eth15:green";
                        gpios = <&sgpio_out0 15 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@15 {
+               led-15 {
                        label = "eth15:yellow";
                        gpios = <&sgpio_out0 15 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@16 {
+               led-16 {
                        label = "eth48:green";
                        gpios = <&sgpio_out1 16 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@17 {
+               led-17 {
                        label = "eth48:yellow";
                        gpios = <&sgpio_out1 16 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@18 {
+               led-18 {
                        label = "eth49:green";
                        gpios = <&sgpio_out1 17 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@19 {
+               led-19 {
                        label = "eth49:yellow";
                        gpios = <&sgpio_out1 17 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@20 {
+               led-20 {
                        label = "eth50:green";
                        gpios = <&sgpio_out1 18 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@21 {
+               led-21 {
                        label = "eth50:yellow";
                        gpios = <&sgpio_out1 18 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@22 {
+               led-22 {
                        label = "eth51:green";
                        gpios = <&sgpio_out1 19 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@23 {
+               led-23 {
                        label = "eth51:yellow";
                        gpios = <&sgpio_out1 19 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@24 {
+               led-24 {
                        label = "eth52:green";
                        gpios = <&sgpio_out1 20 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@25 {
+               led-25 {
                        label = "eth52:yellow";
                        gpios = <&sgpio_out1 20 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@26 {
+               led-26 {
                        label = "eth53:green";
                        gpios = <&sgpio_out1 21 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@27 {
+               led-27 {
                        label = "eth53:yellow";
                        gpios = <&sgpio_out1 21 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@28 {
+               led-28 {
                        label = "eth54:green";
                        gpios = <&sgpio_out1 22 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@29 {
+               led-29 {
                        label = "eth54:yellow";
                        gpios = <&sgpio_out1 22 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@30 {
+               led-30 {
                        label = "eth55:green";
                        gpios = <&sgpio_out1 23 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@31 {
+               led-31 {
                        label = "eth55:yellow";
                        gpios = <&sgpio_out1 23 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@32 {
+               led-32 {
                        label = "eth56:green";
                        gpios = <&sgpio_out1 24 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@33 {
+               led-33 {
                        label = "eth56:yellow";
                        gpios = <&sgpio_out1 24 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@34 {
+               led-34 {
                        label = "eth57:green";
                        gpios = <&sgpio_out1 25 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@35 {
+               led-35 {
                        label = "eth57:yellow";
                        gpios = <&sgpio_out1 25 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@36 {
+               led-36 {
                        label = "eth58:green";
                        gpios = <&sgpio_out1 26 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@37 {
+               led-37 {
                        label = "eth58:yellow";
                        gpios = <&sgpio_out1 26 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@38 {
+               led-38 {
                        label = "eth59:green";
                        gpios = <&sgpio_out1 27 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@39 {
+               led-39 {
                        label = "eth59:yellow";
                        gpios = <&sgpio_out1 27 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@40 {
+               led-40 {
                        label = "eth60:green";
                        gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@41 {
+               led-41 {
                        label = "eth60:yellow";
                        gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@42 {
+               led-42 {
                        label = "eth61:green";
                        gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@43 {
+               led-43 {
                        label = "eth61:yellow";
                        gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@44 {
+               led-44 {
                        label = "eth62:green";
                        gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@45 {
+               led-45 {
                        label = "eth62:yellow";
                        gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@46 {
+               led-46 {
                        label = "eth63:green";
                        gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
-               led@47 {
+               led-47 {
                        label = "eth63:yellow";
                        gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
        };
 };
 
-&spi0 {
-       status = "okay";
-       flash@0 {
-               compatible = "jedec,spi-nor";
-               spi-max-frequency = <8000000>;
-               reg = <0>;
-       };
-};
-
 &spi0 {
        status = "okay";
        spi@0 {
 };
 
 &axi {
-       i2c0_imux: i2c0-imux@0 {
+       i2c0_imux: i2c-mux-0 {
                compatible = "i2c-mux-pinctrl";
                #address-cells = <1>;
                #size-cells = <0>;
                i2c-parent = <&i2c0>;
        };
-       i2c0_emux: i2c0-emux@0 {
+       i2c0_emux: i2c-mux-1 {
                compatible = "i2c-mux-gpio";
                #address-cells = <1>;
                #size-cells = <0>;
        pinctrl-10 = <&i2cmux_10>;
        pinctrl-11 = <&i2cmux_11>;
        pinctrl-12 = <&i2cmux_pins_i>;
-       i2c_sfp1: i2c_sfp1 {
+       i2c_sfp1: i2c@0 {
                reg = <0x0>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp2: i2c_sfp2 {
+       i2c_sfp2: i2c@1 {
                reg = <0x1>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp3: i2c_sfp3 {
+       i2c_sfp3: i2c@2 {
                reg = <0x2>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp4: i2c_sfp4 {
+       i2c_sfp4: i2c@3 {
                reg = <0x3>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp5: i2c_sfp5 {
+       i2c_sfp5: i2c@4 {
                reg = <0x4>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp6: i2c_sfp6 {
+       i2c_sfp6: i2c@5 {
                reg = <0x5>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp7: i2c_sfp7 {
+       i2c_sfp7: i2c@6 {
                reg = <0x6>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp8: i2c_sfp8 {
+       i2c_sfp8: i2c@7 {
                reg = <0x7>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp9: i2c_sfp9 {
+       i2c_sfp9: i2c@8 {
                reg = <0x8>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp10: i2c_sfp10 {
+       i2c_sfp10: i2c@9 {
                reg = <0x9>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp11: i2c_sfp11 {
+       i2c_sfp11: i2c@a {
                reg = <0xa>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp12: i2c_sfp12 {
+       i2c_sfp12: i2c@b {
                reg = <0xb>;
                #address-cells = <1>;
                #size-cells = <0>;
                     &gpio 61 GPIO_ACTIVE_HIGH
                     &gpio 54 GPIO_ACTIVE_HIGH>;
        idle-state = <0x8>;
-       i2c_sfp13: i2c_sfp13 {
+       i2c_sfp13: i2c@0 {
                reg = <0x0>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp14: i2c_sfp14 {
+       i2c_sfp14: i2c@1 {
                reg = <0x1>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp15: i2c_sfp15 {
+       i2c_sfp15: i2c@2 {
                reg = <0x2>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp16: i2c_sfp16 {
+       i2c_sfp16: i2c@3 {
                reg = <0x3>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp17: i2c_sfp17 {
+       i2c_sfp17: i2c@4 {
                reg = <0x4>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp18: i2c_sfp18 {
+       i2c_sfp18: i2c@5 {
                reg = <0x5>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp19: i2c_sfp19 {
+       i2c_sfp19: i2c@6 {
                reg = <0x6>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp20: i2c_sfp20 {
+       i2c_sfp20: i2c@7 {
                reg = <0x7>;
                #address-cells = <1>;
                #size-cells = <0>;
index 82ce007d99592cac131cee3cfb2f5014ff56d3b4..af2f1831f07f890a5e7f8d3593453ad3f78bb098 100644 (file)
 
        leds {
                compatible = "gpio-leds";
-               led@0 {
+               led-0 {
                        label = "eth60:yellow";
                        gpios = <&sgpio_out1 28 0 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@1 {
+               led-1 {
                        label = "eth60:green";
                        gpios = <&sgpio_out1 28 1 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@2 {
+               led-2 {
                        label = "eth61:yellow";
                        gpios = <&sgpio_out1 29 0 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@3 {
+               led-3 {
                        label = "eth61:green";
                        gpios = <&sgpio_out1 29 1 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@4 {
+               led-4 {
                        label = "eth62:yellow";
                        gpios = <&sgpio_out1 30 0 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@5 {
+               led-5 {
                        label = "eth62:green";
                        gpios = <&sgpio_out1 30 1 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@6 {
+               led-6 {
                        label = "eth63:yellow";
                        gpios = <&sgpio_out1 31 0 GPIO_ACTIVE_LOW>;
                        default-state = "off";
                };
-               led@7 {
+               led-7 {
                        label = "eth63:green";
                        gpios = <&sgpio_out1 31 1 GPIO_ACTIVE_LOW>;
                        default-state = "off";
        };
 };
 
-&spi0 {
-       status = "okay";
-       flash@0 {
-               compatible = "jedec,spi-nor";
-               spi-max-frequency = <8000000>;
-               reg = <0>;
-       };
-};
-
 &spi0 {
        status = "okay";
        spi@0 {
 };
 
 &axi {
-       i2c0_imux: i2c0-imux@0 {
+       i2c0_imux: i2c-mux {
                compatible = "i2c-mux-pinctrl";
                #address-cells = <1>;
                #size-cells = <0>;
        pinctrl-2 = <&i2cmux_s31>;
        pinctrl-3 = <&i2cmux_s32>;
        pinctrl-4 = <&i2cmux_pins_i>;
-       i2c_sfp1: i2c_sfp1 {
+       i2c_sfp1: i2c@0 {
                reg = <0x0>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp2: i2c_sfp2 {
+       i2c_sfp2: i2c@1 {
                reg = <0x1>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp3: i2c_sfp3 {
+       i2c_sfp3: i2c@2 {
                reg = <0x2>;
                #address-cells = <1>;
                #size-cells = <0>;
        };
-       i2c_sfp4: i2c_sfp4 {
+       i2c_sfp4: i2c@3 {
                reg = <0x3>;
                #address-cells = <1>;
                #size-cells = <0>;
index a5ab2bc0f8359a8688dca60b0be36216b1d4d352..eeceb5b292a8ff1959b7e4c88f772d3202f82a7b 100644 (file)
@@ -16,7 +16,7 @@
                stdout-path = &serial0;
        };
 
-       memory {
+       memory@0 {
                reg = <0x0 0x0 0x0 0x40000000>;
        };
 };
index 14d58859bb55c99c756d2d4c6f4fc49b0ea84096..683ac124523b3bc55659e6fb9453ed6500e0742e 100644 (file)
@@ -9,8 +9,8 @@
        compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124";
 
        aliases {
-               rtc0 = "/i2c@7000d000/as3722@40";
-               rtc1 = "/rtc@7000e000";
+               rtc0 = &as3722;
+               rtc1 = &tegra_rtc;
                serial0 = &uarta;
        };
 
index 7e24a212c7e449c58bfeba82ea3ab284792e6163..5bcccfef3f7f8c62c017165b39bf8569352779be 100644 (file)
                status = "disabled";
        };
 
-       rtc@7000e000 {
+       tegra_rtc: rtc@7000e000 {
                compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
                reg = <0x0 0x7000e000 0x0 0x100>;
                interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
index 9ebb7369256e02aa28ff75c8f608f7409b07a437..2e5b6b2c1f56ba56eb6c64acbddb7d9e2f033998 100644 (file)
@@ -25,7 +25,7 @@
                stdout-path = "serial0:115200n8";
        };
 
-       memory {
+       memory@80000000 {
                device_type = "memory";
                reg = <0x0 0x80000000 0x0 0xc0000000>;
        };
index 47f8268e46bf1b8c84cfb657c6cd253f24c4fca0..882b1d1f4ada8d9e275e5a6bee633a21cc6cdb2d 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a57-pmu";
                interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
index 78cbfdd98dd12c8bfe3216bf30a6d8d77ce378d2..f2e2d8d6845bf1b95cf059fcba24725e49c5d5d9 100644 (file)
                                 */
                                status = "disabled";
                        };
+
+                       crypto@15820000 {
+                               compatible = "nvidia,tegra234-se-aes";
+                               reg = <0x00 0x15820000 0x00 0x10000>;
+                               clocks = <&bpmp TEGRA234_CLK_SE>;
+                               iommus = <&smmu_niso1 TEGRA234_SID_SES_SE1>;
+                               dma-coherent;
+                       };
+
+                       crypto@15840000 {
+                               compatible = "nvidia,tegra234-se-hash";
+                               reg = <0x00 0x15840000 0x00 0x10000>;
+                               clocks = <&bpmp TEGRA234_CLK_SE>;
+                               iommus = <&smmu_niso1 TEGRA234_SID_SES_SE2>;
+                               dma-coherent;
+                       };
                };
 
                pcie@140a0000 {
index 7d40ec5e7d214c5c72df95e8b83f16b57d4c53ce..f63abb43e9fed435c41def673daf587174688a32 100644 (file)
@@ -241,6 +241,7 @@ dtb-$(CONFIG_ARCH_QCOM)     += sm8450-sony-xperia-nagara-pdx224.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sm8550-hdk.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sm8550-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sm8550-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += sm8550-sony-xperia-yodo-pdx234.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sm8650-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sm8650-qrd.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += x1e80100-crd.dtb
index 9ffad7d1f2b6cb9e700f7d3db7b29ac10b755b5b..aba08424aa38439952f959f79a9ded2201de1f7c 100644 (file)
@@ -91,7 +91,7 @@
 
                compatible = "gpio-leds";
 
-               led@1 {
+               led-1 {
                        label = "apq8016-sbc:green:user1";
                        function = LED_FUNCTION_HEARTBEAT;
                        color = <LED_COLOR_ID_GREEN>;
                        default-state = "off";
                };
 
-               led@2 {
+               led-2 {
                        label = "apq8016-sbc:green:user2";
                        function = LED_FUNCTION_DISK_ACTIVITY;
                        color = <LED_COLOR_ID_GREEN>;
                        default-state = "off";
                };
 
-               led@3 {
+               led-3 {
                        label = "apq8016-sbc:green:user3";
                        function = LED_FUNCTION_DISK_ACTIVITY;
                        color = <LED_COLOR_ID_GREEN>;
                        default-state = "off";
                };
 
-               led@4 {
+               led-4 {
                        label = "apq8016-sbc:green:user4";
                        color = <LED_COLOR_ID_GREEN>;
                        gpios = <&pm8916_gpios 2 GPIO_ACTIVE_HIGH>;
                        default-state = "off";
                };
 
-               led@5 {
+               led-5 {
                        label = "apq8016-sbc:yellow:wlan";
                        function = LED_FUNCTION_WLAN;
                        color = <LED_COLOR_ID_YELLOW>;
                        default-state = "off";
                };
 
-               led@6 {
+               led-6 {
                        label = "apq8016-sbc:blue:bt";
                        function = LED_FUNCTION_BLUETOOTH;
                        color = <LED_COLOR_ID_BLUE>;
index 4e29adea570a063fdd18c31da210d00176ace875..17ab6c4759580c28f09e6bb695e614a669f70df6 100644 (file)
                                      "axi_s_sticky";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
        };
 
index 1b8379ba87f9c778cae214fda62a1cfe5aa01004..34e2f80514a3daf2be4e51c00cbff338d105fef7 100644 (file)
@@ -16,7 +16,7 @@
                stdout-path = "serial0";
        };
 
-       memory {
+       memory@40000000 {
                device_type = "memory";
                reg = <0x0 0x40000000 0x0 0x20000000>;
        };
index e5b89753aa5c12ca1d9e9165c88f5044a2af2924..5d42de829e75f18c0f35479e8390c690de62b266 100644 (file)
                                bias-disable;
                        };
 
+                       serial_5_pins: serial5-state {
+                               pins = "gpio9", "gpio16";
+                               function = "blsp5_uart";
+                               drive-strength = <8>;
+                               bias-disable;
+                       };
+
                        i2c_0_pins: i2c-0-state {
                                pins = "gpio42", "gpio43";
                                function = "blsp1_i2c";
                                       "gpio5", "gpio6", "gpio7",
                                       "gpio8", "gpio10", "gpio11",
                                       "gpio12", "gpio13", "gpio14",
-                                      "gpio15", "gpio16", "gpio17";
+                                      "gpio15", "gpio17";
                                function = "qpic";
                                drive-strength = <8>;
                                bias-disable;
                        status = "disabled";
                };
 
+               blsp1_uart6: serial@78b4000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x078b4000 0x200>;
+                       interrupts = <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_UART6_APPS_CLK>,
+                                <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       pinctrl-0 = <&serial_5_pins>;
+                       pinctrl-names = "default";
+                       status = "disabled";
+               };
+
                blsp1_spi1: spi@78b5000 {
                        compatible = "qcom,spi-qup-v2.2.1";
                        #address-cells = <1>;
                                      "ahb",
                                      "axi_m_sticky";
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0: pcie@20000000 {
                                      "axi_m_sticky",
                                      "axi_s_sticky";
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
        };
 
index 3a3e794c022f91a463086ca6290257977a70528f..7f0c2c1b8a94b2c4d79e5e0b2b7188f4e2b2d281 100644 (file)
@@ -12,7 +12,7 @@
 
 / {
        model = "Longcheer L8150";
-       compatible = "longcheer,l8150", "qcom,msm8916-v1-qrd/9-v1", "qcom,msm8916";
+       compatible = "longcheer,l8150", "qcom,msm8916";
        chassis-type = "handset";
 
        aliases {
index ac527a3a08267a8bf653739b5eab4a13d9517576..c11a845e91bb5029e89905ec7dee3b07646dd4cb 100644 (file)
@@ -9,7 +9,7 @@
 
 / {
        model = "Qualcomm Technologies, Inc. MSM 8916 MTP";
-       compatible = "qcom,msm8916-mtp", "qcom,msm8916-mtp/1", "qcom,msm8916";
+       compatible = "qcom,msm8916-mtp", "qcom,msm8916";
        chassis-type = "handset";
 
        aliases {
index 2937495940ea02abf7d7d537160df8be171f9dd2..4bbbee80b5e4bbb2e5ddcc75b35131ee98a8db3c 100644 (file)
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&muic_int_default>;
+
+                       usb_con: connector {
+                               compatible = "usb-b-connector";
+                               label = "micro-USB";
+                               type = "micro";
+                       };
                };
        };
 
index 3c49dac92d2d4ad88074ec547264acb0398bcd29..c50f81a688973a3987a070e454ca19d0b99312aa 100644 (file)
 
                        pinctrl-names = "default";
                        pinctrl-0 = <&muic_int_default>;
+
+                       usb_con: connector {
+                               compatible = "usb-b-connector";
+                               label = "micro-USB";
+                               type = "micro";
+                       };
                };
        };
 
index c2800ad2dd5b2dc063b5eceb7b4a1d852a75e1a9..5e933fb8b363f99688069dedd7b1f8ba8207949c 100644 (file)
                };
        };
 
+       clk_pwm_backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&clk_pwm 0 100000>;
+
+               enable-gpios = <&tlmm 98 GPIO_ACTIVE_HIGH>;
+
+               brightness-levels = <0 255>;
+               num-interpolated-steps = <255>;
+               default-brightness-level = <128>;
+
+               pinctrl-0 = <&backlight_en_default>;
+               pinctrl-names = "default";
+       };
+
+       clk_pwm: pwm {
+               compatible = "clk-pwm";
+               #pwm-cells = <2>;
+
+               clocks = <&gcc GCC_GP2_CLK>;
+
+               pinctrl-0 = <&backlight_pwm_default>;
+               pinctrl-names = "default";
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
                pinctrl-0 = <&motor_en_default>;
                pinctrl-names = "default";
        };
+
+       reg_vdd_tsp_a: regulator-vdd-tsp-a {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_tsp_a";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+
+               gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-0 = <&tsp_en_default>;
+               pinctrl-names = "default";
+       };
 };
 
 &blsp_i2c1 {
        };
 };
 
+&blsp_i2c5 {
+       status = "okay";
+
+       touchscreen: touchscreen@20 {
+               compatible = "zinitix,bt541";
+               reg = <0x20>;
+
+               interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>;
+
+               touchscreen-size-x = <540>;
+               touchscreen-size-y = <960>;
+
+               vcca-supply = <&reg_vdd_tsp_a>;
+               vdd-supply = <&pm8916_l6>;
+
+               pinctrl-0 = <&tsp_int_default>;
+               pinctrl-names = "default";
+       };
+};
+
 &blsp_uart2 {
        status = "okay";
 };
 };
 
 &tlmm {
+       backlight_en_default: backlight-en-default-state {
+               pins = "gpio98";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       backlight_pwm_default: backlight-pwm-default-state {
+               pins = "gpio50";
+               function = "gcc_gp2_clk_a";
+       };
+
        fg_alert_default: fg-alert-default-state {
                pins = "gpio121";
                function = "gpio";
                drive-strength = <2>;
                bias-disable;
        };
+
+       tsp_en_default: tsp-en-default-state {
+               pins = "gpio73";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       tsp_int_default: tsp-int-default-state {
+               pins = "gpio13";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-disable;
+       };
 };
index 42843771ae2ae5bea1240fcc252fe441997e93d7..b438fa81886c5a31117a27bb6d35aae6db1e1aaf 100644 (file)
@@ -5,6 +5,9 @@
 /* SM5504 MUIC instead of SM5502 */
 /delete-node/ &muic;
 
+/* Touchscreen varies depending on model variant */
+/delete-node/ &touchscreen;
+
 &blsp_i2c1 {
        muic: extcon@14 {
                compatible = "siliconmitus,sm5504-muic";
                pinctrl-names = "default";
        };
 };
+
+/* On rossa backlight is controlled with MIPI DCS commands */
+&clk_pwm {
+       status = "disabled";
+};
+
+&clk_pwm_backlight {
+       status = "disabled";
+};
index aa6c39482a2f13d2c4e3da075937a2124096e33f..0c599e71a464b59448a1281590143da1dbe423aa 100644 (file)
 
                pinctrl-0 = <&muic_int_default>;
                pinctrl-names = "default";
+
+               usb_con: connector {
+                       compatible = "usb-b-connector";
+                       label = "micro-USB";
+                       type = "micro";
+               };
        };
 };
 
index f1011bb641c619c2331fcca2b920151241ead05b..5d818fe057ddb419f89f26363fbc61132ce3dc6d 100644 (file)
                                snps,hird-threshold = /bits/ 8 <0x00>;
 
                                maximum-speed = "high-speed";
+
+                               usb-role-switch;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+
+                                               usb_dwc3_hs: endpoint {
+                                               };
+                                       };
+                               };
                        };
                };
 
index 1601e46549e77990dafbd63894b9c078ffec60af..8d2cb6f410956e84fe58eba0bc384289651c4f2a 100644 (file)
                                                "cfg",
                                                "bus_master",
                                                "bus_slave";
+
+                               pcie@0 {
+                                       device_type = "pci";
+                                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                                       bus-range = <0x01 0xff>;
+
+                                       #address-cells = <3>;
+                                       #size-cells = <2>;
+                                       ranges;
+                               };
                        };
 
                        pcie1: pcie@608000 {
                                                "cfg",
                                                "bus_master",
                                                "bus_slave";
+
+                               pcie@0 {
+                                       device_type = "pci";
+                                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                                       bus-range = <0x01 0xff>;
+
+                                       #address-cells = <3>;
+                                       #size-cells = <2>;
+                                       ranges;
+                               };
                        };
 
                        pcie2: pcie@610000 {
                                                "cfg",
                                                "bus_master",
                                                "bus_slave";
+
+                               pcie@0 {
+                                       device_type = "pci";
+                                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                                       bus-range = <0x01 0xff>;
+
+                                       #address-cells = <3>;
+                                       #size-cells = <2>;
+                                       ranges;
+                               };
                        };
                };
 
index 876c6921ddf0713542fe69d41b1fce9449e3d786..d8cc0d729e99c5ead32f38c12bf65a930d369c08 100644 (file)
        gpio-keys {
                compatible = "gpio-keys";
                label = "Side buttons";
+               pinctrl-0 = <&focus_n &snapshot_n &vol_down_n &vol_up_n>;
                pinctrl-names = "default";
-               pinctrl-0 = <&vol_down_n &focus_n &snapshot_n>;
-               button-vol-down {
-                       label = "Volume Down";
-                       gpios = <&pm8998_gpios 5 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <EV_KEY>;
-                       linux,code = <KEY_VOLUMEDOWN>;
-                       wakeup-source;
+               button-camera-focus {
+                       label = "Camera Focus";
+                       gpios = <&pm8998_gpios 8 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_CAMERA_FOCUS>;
                        debounce-interval = <15>;
                };
 
                button-camera-snapshot {
                        label = "Camera Snapshot";
                        gpios = <&pm8998_gpios 7 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <EV_KEY>;
                        linux,code = <KEY_CAMERA>;
                        debounce-interval = <15>;
                };
 
-               button-camera-focus {
-                       label = "Camera Focus";
-                       gpios = <&pm8998_gpios 8 GPIO_ACTIVE_LOW>;
-                       linux,input-type = <EV_KEY>;
-                       linux,code = <KEY_CAMERA_FOCUS>;
+               button-vol-down {
+                       label = "Volume Down";
+                       gpios = <&pm8998_gpios 5 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       wakeup-source;
+                       debounce-interval = <15>;
+               };
+
+               button-vol-up {
+                       label = "Volume Up";
+                       gpios = <&pm8998_gpios 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       wakeup-source;
                        debounce-interval = <15>;
                };
        };
                qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
        };
 
+       vol_up_n: vol-up-n-state {
+               pins = "gpio6";
+               function = PMIC_GPIO_FUNC_NORMAL;
+               bias-pull-up;
+               input-enable;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+       };
+
        focus_n: focus-n-state {
                pins = "gpio7";
                function = PMIC_GPIO_FUNC_NORMAL;
        };
 };
 
-&pm8998_resin {
-       linux,code = <KEY_VOLUMEUP>;
+&pmi8998_lpg {
+       qcom,power-source = <1>;
+
        status = "okay";
+
+       multi-led {
+               color = <LED_COLOR_ID_RGB>;
+               function = LED_FUNCTION_STATUS;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               led@3 {
+                       reg = <3>;
+                       color = <LED_COLOR_ID_BLUE>;
+               };
+
+               led@4 {
+                       reg = <4>;
+                       color = <LED_COLOR_ID_GREEN>;
+               };
+
+               led@5 {
+                       reg = <5>;
+                       color = <LED_COLOR_ID_RED>;
+               };
+       };
 };
 
 &qusb2phy {
index 4dfe2d09ac2859d1da4341954fc42450696f92ef..d795b2bbe13308610a080a783def4d9955cc8d63 100644 (file)
                        power-domains = <&gcc PCIE_0_GDSC>;
                        iommu-map = <0x100 &anoc1_smmu 0x1480 1>;
                        perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie_phy: phy@1c06000 {
index 11158c2bd5241661da0efb8019952d0b91db05ba..6de6ed562d97ce4174c54b2da8dfef7f96a00db1 100644 (file)
                };
 
                pm6150_vbus: usb-vbus-regulator@1100 {
-                       compatible = "qcom,pm6150-vbus-reg,
-                                     qcom,pm8150b-vbus-reg";
+                       compatible = "qcom,pm6150-vbus-reg",
+                                    "qcom,pm8150b-vbus-reg";
                        reg = <0x1100>;
                        status = "disabled";
                };
 
                pm6150_typec: typec@1500 {
-                       compatible = "qcom,pm6150-typec,
-                                     qcom,pm8150b-typec";
+                       compatible = "qcom,pm6150-typec",
+                                    "qcom,pm8150b-typec";
                        reg = <0x1500>, <0x1700>;
                        interrupts = <0x0 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
                                     <0x0 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
index d13a1ab7c20b34dcd9cc9613d3f488d95bad78f1..0fce45276e5c23eca77de90c49e7a07e2a7ec620 100644 (file)
                        status = "disabled";
                };
 
+               pm6150l_lpg: pwm {
+                       compatible = "qcom,pm6150l-lpg", "qcom,pm8150l-lpg";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #pwm-cells = <2>;
+
+                       status = "disabled";
+               };
+
                pm6150l_wled: leds@d800 {
                        compatible = "qcom,pm6150l-wled";
                        reg = <0xd800>, <0xd900>;
index 89beac833d43552197b88ac5b9d57c239a6bbb39..106110a9f5518d1f31b891166f85c33e18f466cf 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_PPI 6 IRQ_TYPE_LEVEL_HIGH>;
        };
 
                        clock-output-names = "usb3_phy_pipe_clk_src";
 
                        #phy-cells = <0>;
+                       orientation-switch;
 
                        qcom,tcsr-reg = <&tcsr_regs 0xb244>;
 
                        status = "disabled";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       usb_qmpphy_out: endpoint {
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       usb_qmpphy_usb_ss_in: endpoint {
+                                               remote-endpoint = <&usb_dwc3_ss>;
+                                       };
+                               };
+                       };
                };
 
                system_noc: interconnect@1880000 {
                                snps,usb3_lpm_capable;
                                maximum-speed = "super-speed";
                                dr_mode = "otg";
+                               usb-role-switch;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+
+                                               usb_dwc3_hs: endpoint {
+                                               };
+                                       };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               usb_dwc3_ss: endpoint {
+                                                       remote-endpoint = <&usb_qmpphy_usb_ss_in>;
+                                               };
+                                       };
+                               };
                        };
                };
 
                        compatible = "qcom,qcm2290-cpufreq-hw", "qcom,cpufreq-hw";
                        reg = <0x0 0x0f521000 0x0 0x1000>;
                        reg-names = "freq-domain0";
-                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts-extended = <&lmh_cluster 0>;
                        interrupt-names = "dcvsh-irq-0";
                        clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gcc GPLL0>;
                        clock-names = "xo", "alternate";
                        #freq-domain-cells = <1>;
                        #clock-cells = <1>;
                };
+
+               lmh_cluster: lmh@f550800 {
+                       compatible = "qcom,qcm2290-lmh", "qcom,sm8150-lmh";
+                       reg = <0x0 0x0f550800 0x0 0x400>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       cpus = <&CPU0>;
+                       qcom,lmh-temp-arm-millicelsius = <65000>;
+                       qcom,lmh-temp-low-millicelsius = <94500>;
+                       qcom,lmh-temp-high-millicelsius = <95000>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
        };
 
        thermal-zones {
index 4ff9fc24e50e120f51e840191881d22c59aed874..f3432701945f7f35713e05945a6b116ea85ceef6 100644 (file)
@@ -77,6 +77,8 @@
                #address-cells = <1>;
                #size-cells = <0>;
 
+               orientation-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
+
                connector@0 {
                        compatible = "usb-c-connector";
                        reg = <0>;
index e4bfad50a669b18edb60cf0bd9011f61fbf20919..47ca2d000341418d4b5757570dc3ed67ccf1e239 100644 (file)
@@ -9,7 +9,9 @@
 #define PM7250B_SID 8
 #define PM7250B_SID1 9
 
+#include <dt-bindings/input/linux-event-codes.h>
 #include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include "sc7280.dtsi"
 #include "pm7250b.dtsi"
                serial0 = &uart5;
        };
 
+       pm8350c_pwm_backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pm8350c_pwm 3 65535>;
+               enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
+               pinctrl-0 = <&pmic_lcd_bl_en>;
+               pinctrl-names = "default";
+       };
+
        chosen {
                stdout-path = "serial0:115200n8";
        };
 
+       lcd_disp_bias: regulator-lcd-disp-bias {
+               compatible = "regulator-fixed";
+               regulator-name = "lcd_disp_bias";
+               regulator-min-microvolt = <5500000>;
+               regulator-max-microvolt = <5500000>;
+               gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               pinctrl-0 = <&lcd_disp_bias_en>;
+               pinctrl-names = "default";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-0 = <&key_vol_up_default>;
+               pinctrl-names = "default";
+
+               key-volume-up {
+                       label = "Volume_up";
+                       gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+                       wakeup-source;
+                       debounce-interval = <15>;
+                       linux,can-disable;
+               };
+       };
+
        reserved-memory {
                xbl_mem: xbl@80700000 {
                        reg = <0x0 0x80700000 0x0 0x100000>;
                vdd-l14-l16-supply = <&vreg_s8b_1p272>;
 
                vreg_s1b_1p872: smps1 {
+                       regulator-name = "vreg_s1b_1p872";
                        regulator-min-microvolt = <1840000>;
                        regulator-max-microvolt = <2040000>;
                };
 
                vreg_s2b_0p876: smps2 {
+                       regulator-name = "vreg_s2b_0p876";
                        regulator-min-microvolt = <570070>;
                        regulator-max-microvolt = <1050000>;
                };
 
                vreg_s7b_0p972: smps7 {
+                       regulator-name = "vreg_s7b_0p972";
                        regulator-min-microvolt = <535000>;
                        regulator-max-microvolt = <1120000>;
                };
 
                vreg_s8b_1p272: smps8 {
+                       regulator-name = "vreg_s8b_1p272";
                        regulator-min-microvolt = <1200000>;
                        regulator-max-microvolt = <1500000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
                };
 
                vreg_l1b_0p912: ldo1 {
+                       regulator-name = "vreg_l1b_0p912";
                        regulator-min-microvolt = <825000>;
                        regulator-max-microvolt = <925000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l2b_3p072: ldo2 {
+                       regulator-name = "vreg_l2b_3p072";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l3b_0p504: ldo3 {
+                       regulator-name = "vreg_l3b_0p504";
                        regulator-min-microvolt = <312000>;
                        regulator-max-microvolt = <910000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l4b_0p752: ldo4 {
+                       regulator-name = "vreg_l4b_0p752";
                        regulator-min-microvolt = <752000>;
                        regulator-max-microvolt = <820000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                reg_l5b_0p752: ldo5 {
+                       regulator-name = "reg_l5b_0p752";
                        regulator-min-microvolt = <552000>;
                        regulator-max-microvolt = <832000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l6b_1p2: ldo6 {
+                       regulator-name = "vreg_l6b_1p2";
                        regulator-min-microvolt = <1140000>;
                        regulator-max-microvolt = <1260000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l7b_2p952: ldo7 {
+                       regulator-name = "vreg_l7b_2p952";
                        regulator-min-microvolt = <2400000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l8b_0p904: ldo8 {
+                       regulator-name = "vreg_l8b_0p904";
                        regulator-min-microvolt = <870000>;
                        regulator-max-microvolt = <970000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l9b_1p2: ldo9 {
+                       regulator-name = "vreg_l9b_1p2";
                        regulator-min-microvolt = <1200000>;
                        regulator-max-microvolt = <1304000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l11b_1p504: ldo11 {
+                       regulator-name = "vreg_l11b_1p504";
                        regulator-min-microvolt = <1504000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l12b_0p751: ldo12 {
+                       regulator-name = "vreg_l12b_0p751";
                        regulator-min-microvolt = <751000>;
                        regulator-max-microvolt = <824000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l13b_0p53: ldo13 {
+                       regulator-name = "vreg_l13b_0p53";
                        regulator-min-microvolt = <530000>;
                        regulator-max-microvolt = <824000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l14b_1p08: ldo14 {
+                       regulator-name = "vreg_l14b_1p08";
                        regulator-min-microvolt = <1080000>;
                        regulator-max-microvolt = <1304000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l15b_0p765: ldo15 {
+                       regulator-name = "vreg_l15b_0p765";
                        regulator-min-microvolt = <765000>;
                        regulator-max-microvolt = <1020000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l16b_1p1: ldo16 {
+                       regulator-name = "vreg_l16b_1p1";
                        regulator-min-microvolt = <1100000>;
                        regulator-max-microvolt = <1300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l17b_1p7: ldo17 {
+                       regulator-name = "vreg_l17b_1p7";
                        regulator-min-microvolt = <1700000>;
                        regulator-max-microvolt = <1900000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l18b_1p8: ldo18 {
+                       regulator-name = "vreg_l18b_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l19b_1p8: ldo19 {
+                       regulator-name = "vreg_l19b_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                vdd-bob-supply = <&vph_pwr>;
 
                vreg_s1c_2p19: smps1 {
+                       regulator-name = "vreg_s1c_2p19";
                        regulator-min-microvolt = <2190000>;
                        regulator-max-microvolt = <2210000>;
                };
 
                vreg_s2c_0p752: smps2 {
+                       regulator-name = "vreg_s2c_0p752";
                        regulator-min-microvolt = <750000>;
                        regulator-max-microvolt = <800000>;
                };
 
                vreg_s5c_0p752: smps5 {
+                       regulator-name = "vreg_s5c_0p752";
                        regulator-min-microvolt = <465000>;
                        regulator-max-microvolt = <1050000>;
                };
 
                vreg_s7c_0p752: smps7 {
+                       regulator-name = "vreg_s7c_0p752";
                        regulator-min-microvolt = <465000>;
                        regulator-max-microvolt = <800000>;
                };
 
                vreg_s9c_1p084: smps9 {
+                       regulator-name = "vreg_s9c_1p084";
                        regulator-min-microvolt = <1010000>;
                        regulator-max-microvolt = <1170000>;
                };
 
                vreg_l1c_1p8: ldo1 {
+                       regulator-name = "vreg_l1c_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1980000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l2c_1p62: ldo2 {
+                       regulator-name = "vreg_l2c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <1980000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l3c_2p8: ldo3 {
+                       regulator-name = "vreg_l3c_2p8";
                        regulator-min-microvolt = <2800000>;
                        regulator-max-microvolt = <3540000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l4c_1p62: ldo4 {
+                       regulator-name = "vreg_l4c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l5c_1p62: ldo5 {
+                       regulator-name = "vreg_l5c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l6c_2p96: ldo6 {
+                       regulator-name = "vreg_l6c_2p96";
                        regulator-min-microvolt = <1650000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l7c_3p0: ldo7 {
+                       regulator-name = "vreg_l7c_3p0";
                        regulator-min-microvolt = <3000000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l8c_1p62: ldo8 {
+                       regulator-name = "vreg_l8c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l9c_2p96: ldo9 {
+                       regulator-name = "vreg_l9c_2p96";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <35440000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l10c_0p88: ldo10 {
+                       regulator-name = "vreg_l10c_0p88";
                        regulator-min-microvolt = <720000>;
                        regulator-max-microvolt = <1050000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l11c_2p8: ldo11 {
+                       regulator-name = "vreg_l11c_2p8";
                        regulator-min-microvolt = <2800000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l12c_1p65: ldo12 {
+                       regulator-name = "vreg_l12c_1p65";
                        regulator-min-microvolt = <1650000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l13c_2p7: ldo13 {
+                       regulator-name = "vreg_l13c_2p7";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_bob_3p296: bob {
+                       regulator-name = "vreg_bob_3p296";
                        regulator-min-microvolt = <3008000>;
                        regulator-max-microvolt = <3960000>;
                };
        };
 };
 
+&mdss {
+       status = "okay";
+};
+
+&mdss_dsi {
+       vdda-supply = <&vreg_l6b_1p2>;
+       status = "okay";
+
+       panel@0 {
+               compatible = "novatek,nt36672e";
+               reg = <0>;
+
+               reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+
+               vddi-supply = <&vreg_l8c_1p62>;
+               avdd-supply = <&lcd_disp_bias>;
+               avee-supply = <&lcd_disp_bias>;
+
+               backlight = <&pm8350c_pwm_backlight>;
+
+               port {
+                       panel0_in: endpoint {
+                               remote-endpoint = <&mdss_dsi0_out>;
+                       };
+               };
+       };
+};
+
+&mdss_dsi0_out {
+       remote-endpoint = <&panel0_in>;
+       data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+       vdds-supply = <&vreg_l10c_0p88>;
+       status = "okay";
+};
+
+&pm7250b_gpios {
+       lcd_disp_bias_en: lcd-disp-bias-en-state {
+               pins = "gpio2";
+               function = "func1";
+               bias-disable;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+               input-disable;
+               output-enable;
+               power-source = <0>;
+       };
+};
+
+&pm8350c_gpios {
+       pmic_lcd_bl_en: pmic-lcd-bl-en-state {
+               pins = "gpio7";
+               function = "normal";
+               bias-disable;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+               output-low;
+               power-source = <0>;
+       };
+
+       pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
+               pins = "gpio8";
+               function = "func1";
+               bias-disable;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+               output-low;
+               power-source = <0>;
+       };
+};
+
+&pm7325_gpios {
+       key_vol_up_default: key-vol-up-state {
+               pins = "gpio6";
+               function = "normal";
+               input-enable;
+               bias-pull-up;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+       };
+};
+
 &pm8350c_pwm {
+       pinctrl-0 = <&pmic_lcd_bl_pwm>;
+       pinctrl-names = "default";
        status = "okay";
 
        multi-led {
        };
 };
 
+&pon_pwrkey {
+       status = "okay";
+};
+
+&pon_resin {
+       linux,code = <KEY_VOLUMEDOWN>;
+       status = "okay";
+};
+
 &qupv3_id_0 {
        status = "okay";
 };
 
+&remoteproc_adsp {
+       firmware-name = "qcom/qcm6490/adsp.mbn";
+       status = "okay";
+};
+
+&remoteproc_cdsp {
+       firmware-name = "qcom/qcm6490/cdsp.mbn";
+       status = "okay";
+};
+
+&remoteproc_mpss {
+       firmware-name = "qcom/qcm6490/modem.mbn";
+       status = "okay";
+};
+
+&remoteproc_wpss {
+       firmware-name = "qcom/qcm6490/wpss.mbn";
+       status = "okay";
+};
+
 &sdhc_1 {
        non-removable;
        no-sd;
index 10655401528e4e043e1fbfd4a29cdbb9139ae5fb..a22b4501ce1ef5674f0b5cd1a462f12464a38155 100644 (file)
@@ -62,7 +62,7 @@
                vddrf-supply = <&vreg_l1_1p3>;
                vddch0-supply = <&vdd_ch0_3p3>;
 
-               local-bd-address = [ 02 00 00 00 5a ad ];
+               local-bd-address = [ 00 00 00 00 00 00 ];
 
                max-speed = <3200000>;
        };
index a05d0234f7fc0af276824fa5aba82d2abddb5f9c..ac451f378056a759c4efedc3acf94f09632817ab 100644 (file)
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
        };
 
index 97824c769ba34203b569e79dbe20143284e74e48..a085ff5b5fb21d9cc68c8dd970f30d489a40894b 100644 (file)
@@ -17,7 +17,6 @@
 #include "pmk8350.dtsi"
 
 /delete-node/ &ipa_fw_mem;
-/delete-node/ &remoteproc_mpss;
 /delete-node/ &rmtfs_mem;
 /delete-node/ &adsp_mem;
 /delete-node/ &cdsp_mem;
                stdout-path = "serial0:115200n8";
        };
 
+       dp-connector {
+               compatible = "dp-connector";
+               label = "DP";
+               type = "mini";
+
+               hpd-gpios = <&tlmm 60 GPIO_ACTIVE_HIGH>;
+
+               port {
+                       dp_connector_in: endpoint {
+                               remote-endpoint = <&mdss_edp_out>;
+                       };
+               };
+       };
+
        reserved-memory {
                xbl_mem: xbl@80700000 {
                        reg = <0x0 0x80700000 0x0 0x100000>;
                };
        };
 
+       pmic-glink {
+               compatible = "qcom,qcm6490-pmic-glink", "qcom,pmic-glink";
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               connector@0 {
+                       compatible = "usb-c-connector";
+                       reg = <0>;
+                       power-role = "dual";
+                       data-role = "dual";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       pmic_glink_hs_in: endpoint {
+                                               remote-endpoint = <&usb_1_dwc3_hs>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       pmic_glink_ss_in: endpoint {
+                                               remote-endpoint = <&redriver_usb_con_ss>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+
+                                       pmic_glink_sbu_in: endpoint {
+                                               remote-endpoint = <&redriver_usb_con_sbu>;
+                                       };
+                               };
+                       };
+               };
+       };
+
        vph_pwr: vph-pwr-regulator {
                compatible = "regulator-fixed";
                regulator-name = "vph_pwr";
                vdd-l14-l16-supply = <&vreg_s8b_1p272>;
 
                vreg_s1b_1p872: smps1 {
+                       regulator-name = "vreg_s1b_1p872";
                        regulator-min-microvolt = <1840000>;
                        regulator-max-microvolt = <2040000>;
                };
 
                vreg_s2b_0p876: smps2 {
+                       regulator-name = "vreg_s2b_0p876";
                        regulator-min-microvolt = <570070>;
                        regulator-max-microvolt = <1050000>;
                };
 
                vreg_s7b_0p972: smps7 {
+                       regulator-name = "vreg_s7b_0p972";
                        regulator-min-microvolt = <535000>;
                        regulator-max-microvolt = <1120000>;
                };
 
                vreg_s8b_1p272: smps8 {
+                       regulator-name = "vreg_s8b_1p272";
                        regulator-min-microvolt = <1200000>;
                        regulator-max-microvolt = <1500000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
                };
 
                vreg_l1b_0p912: ldo1 {
+                       regulator-name = "vreg_l1b_0p912";
                        regulator-min-microvolt = <825000>;
                        regulator-max-microvolt = <925000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l2b_3p072: ldo2 {
+                       regulator-name = "vreg_l2b_3p072";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l3b_0p504: ldo3 {
+                       regulator-name = "vreg_l3b_0p504";
                        regulator-min-microvolt = <312000>;
                        regulator-max-microvolt = <910000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l4b_0p752: ldo4 {
+                       regulator-name = "vreg_l4b_0p752";
                        regulator-min-microvolt = <752000>;
                        regulator-max-microvolt = <820000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                reg_l5b_0p752: ldo5 {
+                       regulator-name = "reg_l5b_0p752";
                        regulator-min-microvolt = <552000>;
                        regulator-max-microvolt = <832000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l6b_1p2: ldo6 {
+                       regulator-name = "vreg_l6b_1p2";
                        regulator-min-microvolt = <1140000>;
                        regulator-max-microvolt = <1260000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l7b_2p952: ldo7 {
-                       regulator-min-microvolt = <2400000>;
-                       regulator-max-microvolt = <3544000>;
+                       regulator-name = "vreg_l7b_2p952";
+                       regulator-min-microvolt = <2952000>;
+                       regulator-max-microvolt = <2952000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l8b_0p904: ldo8 {
+                       regulator-name = "vreg_l8b_0p904";
                        regulator-min-microvolt = <870000>;
                        regulator-max-microvolt = <970000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l9b_1p2: ldo9 {
+                       regulator-name = "vreg_l9b_1p2";
                        regulator-min-microvolt = <1200000>;
-                       regulator-max-microvolt = <1304000>;
+                       regulator-max-microvolt = <1200000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-allow-set-load;
+                       regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+                                                  RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l11b_1p504: ldo11 {
+                       regulator-name = "vreg_l11b_1p504";
                        regulator-min-microvolt = <1504000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l12b_0p751: ldo12 {
+                       regulator-name = "vreg_l12b_0p751";
                        regulator-min-microvolt = <751000>;
                        regulator-max-microvolt = <824000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l13b_0p53: ldo13 {
+                       regulator-name = "vreg_l13b_0p53";
                        regulator-min-microvolt = <530000>;
                        regulator-max-microvolt = <824000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l14b_1p08: ldo14 {
+                       regulator-name = "vreg_l14b_1p08";
                        regulator-min-microvolt = <1080000>;
                        regulator-max-microvolt = <1304000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l15b_0p765: ldo15 {
+                       regulator-name = "vreg_l15b_0p765";
                        regulator-min-microvolt = <765000>;
                        regulator-max-microvolt = <1020000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l16b_1p1: ldo16 {
+                       regulator-name = "vreg_l16b_1p1";
                        regulator-min-microvolt = <1100000>;
                        regulator-max-microvolt = <1300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l17b_1p7: ldo17 {
+                       regulator-name = "vreg_l17b_1p7";
                        regulator-min-microvolt = <1700000>;
                        regulator-max-microvolt = <1900000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l18b_1p8: ldo18 {
+                       regulator-name = "vreg_l18b_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l19b_1p8: ldo19 {
+                       regulator-name = "vreg_l19b_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                vdd-bob-supply = <&vph_pwr>;
 
                vreg_s1c_2p19: smps1 {
+                       regulator-name = "vreg_s1c_2p19";
                        regulator-min-microvolt = <2190000>;
                        regulator-max-microvolt = <2210000>;
                };
 
                vreg_s2c_0p752: smps2 {
+                       regulator-name = "vreg_s2c_0p752";
                        regulator-min-microvolt = <750000>;
                        regulator-max-microvolt = <800000>;
                };
 
                vreg_s5c_0p752: smps5 {
+                       regulator-name = "vreg_s5c_0p752";
                        regulator-min-microvolt = <465000>;
                        regulator-max-microvolt = <1050000>;
                };
 
                vreg_s7c_0p752: smps7 {
+                       regulator-name = "vreg_s7c_0p752";
                        regulator-min-microvolt = <465000>;
                        regulator-max-microvolt = <800000>;
                };
 
                vreg_s9c_1p084: smps9 {
+                       regulator-name = "vreg_s9c_1p084";
                        regulator-min-microvolt = <1010000>;
                        regulator-max-microvolt = <1170000>;
                };
 
                vreg_l1c_1p8: ldo1 {
+                       regulator-name = "vreg_l1c_1p8";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1980000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l2c_1p62: ldo2 {
+                       regulator-name = "vreg_l2c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <1980000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l3c_2p8: ldo3 {
+                       regulator-name = "vreg_l3c_2p8";
                        regulator-min-microvolt = <2800000>;
                        regulator-max-microvolt = <3540000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l4c_1p62: ldo4 {
+                       regulator-name = "vreg_l4c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l5c_1p62: ldo5 {
+                       regulator-name = "vreg_l5c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l6c_2p96: ldo6 {
+                       regulator-name = "vreg_l6c_2p96";
                        regulator-min-microvolt = <1650000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l7c_3p0: ldo7 {
+                       regulator-name = "vreg_l7c_3p0";
                        regulator-min-microvolt = <3000000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l8c_1p62: ldo8 {
+                       regulator-name = "vreg_l8c_1p62";
                        regulator-min-microvolt = <1620000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l9c_2p96: ldo9 {
+                       regulator-name = "vreg_l9c_2p96";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <35440000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l10c_0p88: ldo10 {
+                       regulator-name = "vreg_l10c_0p88";
                        regulator-min-microvolt = <720000>;
                        regulator-max-microvolt = <1050000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l11c_2p8: ldo11 {
+                       regulator-name = "vreg_l11c_2p8";
                        regulator-min-microvolt = <2800000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l12c_1p65: ldo12 {
+                       regulator-name = "vreg_l12c_1p65";
                        regulator-min-microvolt = <1650000>;
                        regulator-max-microvolt = <2000000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_l13c_2p7: ldo13 {
+                       regulator-name = "vreg_l13c_2p7";
                        regulator-min-microvolt = <2700000>;
                        regulator-max-microvolt = <3544000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
                vreg_bob_3p296: bob {
+                       regulator-name = "vreg_bob_3p296";
                        regulator-min-microvolt = <3008000>;
                        regulator-max-microvolt = <3960000>;
                };
                           <GCC_WPSS_RSCP_CLK>;
 };
 
+&i2c1 {
+       status = "okay";
+
+       typec-mux@1c {
+               compatible = "onnn,nb7vpq904m";
+               reg = <0x1c>;
+
+               vcc-supply = <&vreg_l18b_1p8>;
+
+               retimer-switch;
+               orientation-switch;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               redriver_usb_con_ss: endpoint {
+                                       remote-endpoint = <&pmic_glink_ss_in>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               redriver_phy_con_ss: endpoint {
+                                       remote-endpoint = <&usb_dp_qmpphy_out>;
+                                       data-lanes = <0 1 2 3>;
+                               };
+                       };
+
+                       port@2 {
+                               reg = <2>;
+
+                               redriver_usb_con_sbu: endpoint {
+                                       remote-endpoint = <&pmic_glink_sbu_in>;
+                               };
+                       };
+               };
+       };
+};
+
+&mdss {
+       status = "okay";
+};
+
+&mdss_dp {
+       status = "okay";
+};
+
+&mdss_dp_out {
+       data-lanes = <0 1>;
+       remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
+&mdss_edp {
+       status = "okay";
+};
+
+&mdss_edp_out {
+       data-lanes = <0 1 2 3>;
+       link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
+       remote-endpoint = <&dp_connector_in>;
+};
+
+&mdss_edp_phy {
+       status = "okay";
+};
+
 &qupv3_id_0 {
        status = "okay";
 };
 
+&remoteproc_adsp {
+       firmware-name = "qcom/qcs6490/adsp.mbn";
+       status = "okay";
+};
+
+&remoteproc_cdsp {
+       firmware-name = "qcom/qcs6490/cdsp.mbn";
+       status = "okay";
+};
+
+&remoteproc_mpss {
+       firmware-name = "qcom/qcs6490/modem.mdt";
+       status = "okay";
+};
+
+&remoteproc_wpss {
+       firmware-name = "qcom/qcs6490/wpss.mbn";
+       status = "okay";
+};
+
 &tlmm {
        gpio-reserved-ranges = <32 2>, /* ADSP */
                               <48 4>; /* NFC */
 };
 
 &usb_1_dwc3 {
-       dr_mode = "peripheral";
+       dr_mode = "otg";
+       usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+       remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+       remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
 };
 
 &usb_1_hsphy {
        vdda-phy-supply = <&vreg_l6b_1p2>;
        vdda-pll-supply = <&vreg_l1b_0p912>;
 
+       orientation-switch;
+
+       status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+       remote-endpoint = <&redriver_phy_con_ss>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+       remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
+&usb_dp_qmpphy_dp_in {
+       remote-endpoint = <&mdss_dp_out>;
+};
+
+&ufs_mem_hc {
+       reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+       vcc-supply = <&vreg_l7b_2p952>;
+       vcc-max-microamp = <800000>;
+       vccq-supply = <&vreg_l9b_1p2>;
+       vccq-max-microamp = <900000>;
+       vccq2-supply = <&vreg_l9b_1p2>;
+       vccq2-max-microamp = <900000>;
+
+       status = "okay";
+};
+
+&ufs_mem_phy {
+       vdda-phy-supply = <&vreg_l10c_0p88>;
+       vdda-pll-supply = <&vreg_l6b_1p2>;
+
        status = "okay";
 };
 
 &wifi {
        memory-region = <&wlan_fw_mem>;
 };
+
+/* PINCTRL - ADDITIONS TO NODES IN PARENT DEVICE TREE FILES */
+
+&edp_hot_plug_det {
+       function = "gpio";
+       bias-disable;
+};
index 832f472c4b7a5ef05a6a5f8e6c537f64b4d1a14c..f2a5e2e40461fec72262e7d0b9957bafdb96ca67 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a55-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
index 6e9dd0312adc5d369136fedbbd6166f7a6f7390c..bb5191422660b82ef243fb111fb9d2515247a80e 100644 (file)
        status = "okay";
 };
 
+&pm4125_typec {
+       status = "okay";
+
+       connector {
+               compatible = "usb-c-connector";
+
+               power-role = "dual";
+               data-role = "dual";
+               self-powered;
+
+               typec-power-opmode = "default";
+               pd-disable;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               pm4125_hs_in: endpoint {
+                                       remote-endpoint = <&usb_dwc3_hs>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               pm4125_ss_in: endpoint {
+                                       remote-endpoint = <&usb_qmpphy_out>;
+                               };
+                       };
+               };
+       };
+};
+
+&pm4125_vbus {
+       regulator-min-microamp = <500000>;
+       regulator-max-microamp = <500000>;
+       status = "okay";
+};
+
 &qupv3_id_0 {
        status = "okay";
 };
        status = "okay";
 };
 
-&usb_qmpphy {
-       vdda-phy-supply = <&pm4125_l12>;
-       vdda-pll-supply = <&pm4125_l13>;
-       status = "okay";
-};
-
-&usb_dwc3 {
-       dr_mode = "host";
+&usb_dwc3_hs {
+       remote-endpoint = <&pm4125_hs_in>;
 };
 
 &usb_hsphy {
        status = "okay";
 };
 
+&usb_qmpphy {
+       vdda-phy-supply = <&pm4125_l12>;
+       vdda-pll-supply = <&pm4125_l13>;
+       status = "okay";
+};
+
+&usb_qmpphy_out {
+       remote-endpoint = <&pm4125_ss_in>;
+};
+
 &wifi {
        vdd-0.8-cx-mx-supply = <&pm4125_l7>;
        vdd-1.8-xo-supply = <&pm4125_l13>;
        vdd-1.3-rfa-supply = <&pm4125_l10>;
        vdd-3.3-ch0-supply = <&pm4125_l22>;
        qcom,ath10k-calibration-variant = "Thundercomm_RB1";
+       firmware-name = "qcm2290";
        status = "okay";
 };
 
index 696d6d43c56b326f5eff21b57cc28daad94c70c1..2c39bb1b97db5121f0e0e9c3d660df5390b561ac 100644 (file)
        vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
        vdd-3.3-ch0-supply = <&vreg_l23a_3p3>;
        qcom,ath10k-calibration-variant = "Thundercomm_RB2";
+       firmware-name = "qrb4210";
 
        status = "okay";
 };
index 5e4287f8c8cd19c84181b9533b9476eb0f7927ca..9e9c7f81096bbafe771780698da19a7e2f908416 100644 (file)
 
                vreg_l13c_2p96: ldo13 {
                        regulator-name = "vreg_l13c_2p96";
-                       regulator-min-microvolt = <2504000>;
+                       regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <2960000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
        };
 };
 
+&pmm8155au_1_gpios {
+       pmm8155au_1_sdc2_cd: sdc2-cd-default-state {
+               pins = "gpio4";
+               function = "normal";
+               input-enable;
+               bias-pull-up;
+               power-source = <0>;
+       };
+};
+
 &qupv3_id_1 {
        status = "okay";
 };
 &sdhc_2 {
        status = "okay";
 
-       cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+       cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>;
        pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sdc2_on>;
-       pinctrl-1 = <&sdc2_off>;
+       pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>;
+       pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>;
        vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */
        vmmc-supply = <&vreg_l17a_2p96>;  /* Card power line */
        bus-width = <4>;
                        bias-pull-up;           /* pull up */
                        drive-strength = <16>;  /* 16 MA */
                };
-
-               sd-cd-pins {
-                       pins = "gpio96";
-                       function = "gpio";
-                       bias-pull-up;           /* pull up */
-                       drive-strength = <2>;   /* 2 MA */
-               };
        };
 
        sdc2_off: sdc2-off-state {
                        bias-pull-up;           /* pull up */
                        drive-strength = <2>;   /* 2 MA */
                };
-
-               sd-cd-pins {
-                       pins = "gpio96";
-                       function = "gpio";
-                       bias-pull-up;           /* pull up */
-                       drive-strength = <2>;   /* 2 MA */
-               };
        };
 
        usb2phy_ac_en1_default: usb2phy-ac-en1-default-state {
index 231cea1f0fa8f46d890146ed8d7f469bbf40d210..31de73594839097da9cadf21c3fb74385537be7e 100644 (file)
                phy-names = "pciephy";
 
                status = "disabled";
+
+               pcie@0 {
+                       device_type = "pci";
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       bus-range = <0x01 0xff>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+               };
        };
 
        pcie0_phy: phy@1c04000 {
                phy-names = "pciephy";
 
                status = "disabled";
+
+               pcie@0 {
+                       device_type = "pci";
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       bus-range = <0x01 0xff>;
+
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       ranges;
+               };
        };
 
        pcie1_phy: phy@1c14000 {
index 5260c63db0078ba6689b1cf3e016134810aa995a..8513be29712013fdbaa9cb125350af992b8773a4 100644 (file)
@@ -1167,6 +1167,7 @@ ap_spi_fp: &spi10 {
 };
 
 &pm6150l_gpios {
+       status = "disabled"; /* No GPIOs are consumed or configured */
        gpio-line-names = "AP_SUSPEND",
                          "",
                          "",
index 2b481e20ae38f74000f8bbf7dd2a26f103465f0b..4774a859bd7eace07b9cde6ea09ce7aac79931a8 100644 (file)
                        compatible = "qcom,sc7180-qmp-ufs-phy",
                                     "qcom,sm7150-qmp-ufs-phy";
                        reg = <0 0x01d87000 0 0x1000>;
-                       clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
-                                <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
-                       clock-names = "ref", "ref_aux";
+                       clocks = <&rpmhcc RPMH_CXO_CLK>,
+                                <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+                                <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+                       clock-names = "ref",
+                                     "ref_aux",
+                                     "qref";
                        power-domains = <&gcc UFS_PHY_GDSC>;
                        resets = <&ufs_mem_hc 0>;
                        reset-names = "ufsphy";
                        compatible = "qcom,sc7180-dcc", "qcom,dcc";
                        reg = <0x0 0x010a2000 0x0 0x1000>,
                              <0x0 0x010ae000 0x0 0x2000>;
+                       status = "disabled";
                };
 
                stm@6002000 {
index 41f51d32611107ef84d30034d703c89b32f7dec2..fc9ec367e3a5a7357236e0569aece65714fe9559 100644 (file)
                                    <0x100 &apps_smmu 0x1c81 0x1>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                                <0 0>,
                                <0 0>,
                                <0 0>;
+                       qcom,ice = <&ice>;
+
                        status = "disabled";
                };
 
                        status = "disabled";
                };
 
+               ice: crypto@1d88000 {
+                       compatible = "qcom,sc7280-inline-crypto-engine",
+                                    "qcom,inline-crypto-engine";
+                       reg = <0 0x01d88000 0 0x8000>;
+                       clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+               };
+
                cryptobam: dma-controller@1dc4000 {
                        compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
                        reg = <0x0 0x01dc4000 0x0 0x28000>;
                                                opp-hz = /bits/ 64 <506666667>;
                                                required-opps = <&rpmhpd_opp_nom>;
                                        };
+
+                                       opp-608000000 {
+                                               opp-hz = /bits/ 64 <608000000>;
+                                               required-opps = <&rpmhpd_opp_turbo>;
+                                       };
                                };
                        };
 
index 0c22f3efec20c8fd2430151c783834d2f89b5823..6af99116c7158d77e5d68ca2e9025d536afbe143 100644 (file)
@@ -51,6 +51,8 @@
 
                #address-cells = <1>;
                #size-cells = <0>;
+               orientation-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>,
+                                   <&tlmm 58 GPIO_ACTIVE_HIGH>;
 
                connector@0 {
                        compatible = "usb-c-connector";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+                                                  RPMH_REGULATOR_MODE_HPM>;
+                       regulator-allow-set-load;
                };
 
                vreg_l10e_2p9: ldo10 {
                        regulator-min-microvolt = <2904000>;
                        regulator-max-microvolt = <2904000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+                                                  RPMH_REGULATOR_MODE_HPM>;
+                       regulator-allow-set-load;
                };
 
                vreg_l16e_3p0: ldo16 {
 
        zap-shader {
                memory-region = <&gpu_mem>;
-               firmware-name = "qcom/sc8180x/qcdxkmsuc8180.mbn";
+               firmware-name = "qcom/sc8180x/LENOVO/82AK/qcdxkmsuc8180.mbn";
        };
 };
 
 &i2c1 {
        clock-frequency = <100000>;
 
-       pinctrl-0 = <&i2c1_active>, <&i2c1_hid_active>;
+       pinctrl-0 = <&i2c1_active>;
        pinctrl-names = "default";
 
        status = "okay";
 
-       hid@10 {
+       touchscreen@10 {
                compatible = "hid-over-i2c";
                reg = <0x10>;
                hid-descr-addr = <0x1>;
 
                interrupts-extended = <&tlmm 122 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-0 = <&ts_int_default>;
+               pinctrl-names = "default";
        };
 };
 
 &i2c7 {
-       clock-frequency = <100000>;
+       clock-frequency = <1000000>;
 
-       pinctrl-0 = <&i2c7_active>, <&i2c7_hid_active>;
+       pinctrl-0 = <&i2c7_active>;
        pinctrl-names = "default";
 
        status = "okay";
 
-       hid@5 {
+       keyboard@5 {
                compatible = "hid-over-i2c";
                reg = <0x5>;
                hid-descr-addr = <0x20>;
 
                interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-0 = <&kb_int_default>;
+               pinctrl-names = "default";
        };
 
-       hid@2c {
+       touchpad@2c {
                compatible = "hid-over-i2c";
                reg = <0x2c>;
                hid-descr-addr = <0x20>;
 
                interrupts-extended = <&tlmm 24 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-0 = <&tp_int_default>;
+               pinctrl-names = "default";
        };
 };
 
                drive-strength = <2>;
        };
 
-       i2c1_hid_active: i2c1-hid-active-state {
-               pins = "gpio122";
-               function = "gpio";
-
-               bias-pull-up;
-               drive-strength = <2>;
-       };
-
        i2c7_active: i2c7-active-state {
                pins = "gpio98", "gpio99";
                function = "qup7";
                drive-strength = <2>;
        };
 
-       i2c7_hid_active: i2c7-hid-active-state {
-               pins = "gpio37", "gpio24";
+       kb_int_default: kb-int-default-state {
+               pins = "gpio37";
                function = "gpio";
 
                bias-pull-up;
                };
        };
 
+       tp_int_default: tp-int-default-state {
+               pins = "gpio24";
+               function = "gpio";
+
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+
+       ts_int_default: ts-int-default-state {
+               pins = "gpio122";
+               function = "gpio";
+
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+
        usbprim_sbu_default: usbprim-sbu-state {
                oe-n-pins {
                        pins = "gpio152";
index 053f7861c3ceced82c3dfb0cf539f94c9c2f64a5..0677123105602d42b9fb7430dafa21a776ed784e 100644 (file)
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie3_phy: phy@1c0c000 {
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c16000 {
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie2_phy: phy@1c1c000 {
 
                gpu: gpu@2c00000 {
                        compatible = "qcom,adreno-680.1", "qcom,adreno";
-                       #stream-id-cells = <16>;
 
                        reg = <0 0x02c00000 0 0x40000>;
                        reg-names = "kgsl_3d0_reg_memory";
                                power-domains = <&rpmhpd SC8180X_MMCX>;
 
                                interrupt-parent = <&mdss>;
-                               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <0>;
 
                                ports {
                                        #address-cells = <1>;
                                reg-names = "dsi_ctrl";
 
                                interrupt-parent = <&mdss>;
-                               interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <4>;
 
                                clocks = <&dispcc DISP_CC_MDSS_BYTE0_CLK>,
                                         <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
                                reg-names = "dsi_ctrl";
 
                                interrupt-parent = <&mdss>;
-                               interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <5>;
 
                                clocks = <&dispcc DISP_CC_MDSS_BYTE1_CLK>,
                                         <&dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
                                reg = <0 0xae90000 0 0x200>,
                                      <0 0xae90200 0 0x200>,
                                      <0 0xae90400 0 0x600>,
-                                     <0 0xae90a00 0 0x400>;
+                                     <0 0xae90a00 0 0x400>,
+                                     <0 0xae91000 0 0x400>;
                                interrupt-parent = <&mdss>;
                                interrupts = <12>;
                                clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
                                reg = <0 0xae98000 0 0x200>,
                                      <0 0xae98200 0 0x200>,
                                      <0 0xae98400 0 0x600>,
-                                     <0 0xae98a00 0 0x400>;
+                                     <0 0xae98a00 0 0x400>,
+                                     <0 0xae99000 0 0x400>;
                                interrupt-parent = <&mdss>;
                                interrupts = <13>;
                                clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
index 15ae94c1602d59ba2b3aa5fd954fabca95b667f4..e937732abeded972eb86af841549576092c31995 100644 (file)
 
                #address-cells = <1>;
                #size-cells = <0>;
+               orientation-gpios = <&tlmm 166 GPIO_ACTIVE_HIGH>,
+                                   <&tlmm 49 GPIO_ACTIVE_HIGH>;
 
                connector@0 {
                        compatible = "usb-c-connector";
                        regulator-always-on;
                };
 
+               vreg_l1b: ldo1 {
+                       regulator-name = "vreg_l1b";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
                vreg_l3b: ldo3 {
                        regulator-name = "vreg_l3b";
                        regulator-min-microvolt = <1200000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
+               vreg_l8c: ldo8 {
+                       regulator-name = "vreg_l8c";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
                vreg_l12c: ldo12 {
                        regulator-name = "vreg_l12c";
                        regulator-min-microvolt = <1800000>;
                vdd-l6-l9-l10-supply = <&vreg_s12b>;
                vdd-l8-supply = <&vreg_s12b>;
 
+               vreg_l2d: ldo2 {
+                       regulator-name = "vreg_l2d";
+                       regulator-min-microvolt = <3072000>;
+                       regulator-max-microvolt = <3072000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
                vreg_l3d: ldo3 {
                        regulator-name = "vreg_l3d";
                        regulator-min-microvolt = <1200000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
 
+               vreg_l8d: ldo8 {
+                       regulator-name = "vreg_l8d";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
                vreg_l9d: ldo9 {
                        regulator-name = "vreg_l9d";
                        regulator-min-microvolt = <912000>;
                        regulator-max-microvolt = <912000>;
                        regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
                };
+
+               vreg_l10d: ldo10 {
+                       regulator-name = "vreg_l10d";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
        };
 };
 
        pinctrl-0 = <&pcie4_default>;
 
        status = "okay";
+};
 
-       pcie@0 {
-               device_type = "pci";
-               reg = <0x0 0x0 0x0 0x0 0x0>;
-               #address-cells = <3>;
-               #size-cells = <2>;
-               ranges;
-
-               bus-range = <0x01 0xff>;
-
-               wifi@0 {
-                       compatible = "pci17cb,1103";
-                       reg = <0x10000 0x0 0x0 0x0 0x0>;
+&pcie4_port0 {
+       wifi@0 {
+               compatible = "pci17cb,1103";
+               reg = <0x10000 0x0 0x0 0x0 0x0>;
 
-                       qcom,ath11k-calibration-variant = "LE_X13S";
-               };
+               qcom,ath11k-calibration-variant = "LE_X13S";
        };
 };
 
        remote-endpoint = <&pmic_glink_con1_hs>;
 };
 
+&usb_2 {
+       status = "okay";
+};
+
+&usb_2_hsphy0 {
+       vdda-pll-supply = <&vreg_l1b>;
+       vdda18-supply = <&vreg_l1c>;
+       vdda33-supply = <&vreg_l7d>;
+
+       status = "okay";
+};
+
+&usb_2_hsphy1 {
+       vdda-pll-supply = <&vreg_l8d>;
+       vdda18-supply = <&vreg_l1c>;
+       vdda33-supply = <&vreg_l7d>;
+
+       status = "okay";
+};
+
+&usb_2_hsphy2 {
+       vdda-pll-supply = <&vreg_l10d>;
+       vdda18-supply = <&vreg_l8c>;
+       vdda33-supply = <&vreg_l2d>;
+
+       status = "okay";
+};
+
+&usb_2_hsphy3 {
+       vdda-pll-supply = <&vreg_l10d>;
+       vdda18-supply = <&vreg_l8c>;
+       vdda33-supply = <&vreg_l2d>;
+
+       status = "okay";
+};
+
+&usb_2_qmpphy0 {
+       vdda-phy-supply = <&vreg_l1b>;
+       vdda-pll-supply = <&vreg_l4d>;
+
+       status = "okay";
+};
+
+&usb_2_qmpphy1 {
+       vdda-phy-supply = <&vreg_l8d>;
+       vdda-pll-supply = <&vreg_l4d>;
+
+       status = "okay";
+};
+
 &vamacro {
        pinctrl-0 = <&dmic01_default>, <&dmic23_default>;
        pinctrl-names = "default";
index d0f82e12289e1b53f1d01592a2131932a48866c5..0549ba1fbeea897b490b614b029cc24578c0370b 100644 (file)
@@ -50,7 +50,8 @@
                        reg = <0x0 0x0>;
                        clocks = <&cpufreq_hw 0>;
                        enable-method = "psci";
-                       capacity-dmips-mhz = <602>;
+                       capacity-dmips-mhz = <981>;
+                       dynamic-power-coefficient = <549>;
                        next-level-cache = <&L2_0>;
                        power-domains = <&CPU_PD0>;
                        power-domain-names = "psci";
@@ -77,7 +78,8 @@
                        reg = <0x0 0x100>;
                        clocks = <&cpufreq_hw 0>;
                        enable-method = "psci";
-                       capacity-dmips-mhz = <602>;
+                       capacity-dmips-mhz = <981>;
+                       dynamic-power-coefficient = <549>;
                        next-level-cache = <&L2_100>;
                        power-domains = <&CPU_PD1>;
                        power-domain-names = "psci";
                        reg = <0x0 0x200>;
                        clocks = <&cpufreq_hw 0>;
                        enable-method = "psci";
-                       capacity-dmips-mhz = <602>;
+                       capacity-dmips-mhz = <981>;
+                       dynamic-power-coefficient = <549>;
                        next-level-cache = <&L2_200>;
                        power-domains = <&CPU_PD2>;
                        power-domain-names = "psci";
                        reg = <0x0 0x300>;
                        clocks = <&cpufreq_hw 0>;
                        enable-method = "psci";
-                       capacity-dmips-mhz = <602>;
+                       capacity-dmips-mhz = <981>;
+                       dynamic-power-coefficient = <549>;
                        next-level-cache = <&L2_300>;
                        power-domains = <&CPU_PD3>;
                        power-domain-names = "psci";
                        clocks = <&cpufreq_hw 1>;
                        enable-method = "psci";
                        capacity-dmips-mhz = <1024>;
+                       dynamic-power-coefficient = <590>;
                        next-level-cache = <&L2_400>;
                        power-domains = <&CPU_PD4>;
                        power-domain-names = "psci";
                        clocks = <&cpufreq_hw 1>;
                        enable-method = "psci";
                        capacity-dmips-mhz = <1024>;
+                       dynamic-power-coefficient = <590>;
                        next-level-cache = <&L2_500>;
                        power-domains = <&CPU_PD5>;
                        power-domain-names = "psci";
                        clocks = <&cpufreq_hw 1>;
                        enable-method = "psci";
                        capacity-dmips-mhz = <1024>;
+                       dynamic-power-coefficient = <590>;
                        next-level-cache = <&L2_600>;
                        power-domains = <&CPU_PD6>;
                        power-domain-names = "psci";
                        clocks = <&cpufreq_hw 1>;
                        enable-method = "psci";
                        capacity-dmips-mhz = <1024>;
+                       dynamic-power-coefficient = <590>;
                        next-level-cache = <&L2_700>;
                        power-domains = <&CPU_PD7>;
                        power-domain-names = "psci";
                scm: scm {
                        compatible = "qcom,scm-sc8280xp", "qcom,scm";
                        interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
+                       qcom,dload-mode = <&tcsr 0x13000>;
                };
        };
 
                        #mbox-cells = <2>;
                };
 
+               qfprom: efuse@784000 {
+                       compatible = "qcom,sc8280xp-qfprom", "qcom,qfprom";
+                       reg = <0 0x00784000 0 0x3000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       gpu_speed_bin: gpu-speed-bin@18b {
+                               reg = <0x18b 0x1>;
+                               bits = <5 3>;
+                       };
+               };
+
                qup2: geniqup@8c0000 {
                        compatible = "qcom,geni-se-qup";
                        reg = <0 0x008c0000 0 0x2000>;
                        linux,pci-domain = <6>;
                        num-lanes = <1>;
 
+                       msi-map = <0x0 &its 0xe0000 0x10000>;
+
                        interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie4_port0: pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie4_phy: phy@1c06000 {
                        linux,pci-domain = <5>;
                        num-lanes = <2>;
 
+                       msi-map = <0x0 &its 0xd0000 0x10000>;
+
                        interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie3b_port0: pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie3b_phy: phy@1c0e000 {
                        linux,pci-domain = <4>;
                        num-lanes = <4>;
 
+                       msi-map = <0x0 &its 0xc0000 0x10000>;
+
                        interrupts = <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie3a_port0: pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie3a_phy: phy@1c14000 {
                        linux,pci-domain = <3>;
                        num-lanes = <2>;
 
+                       msi-map = <0x0 &its 0xb0000 0x10000>;
+
                        interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie2b_port0: pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie2b_phy: phy@1c1e000 {
                        linux,pci-domain = <2>;
                        num-lanes = <4>;
 
+                       msi-map = <0x0 &its 0xa0000 0x10000>;
+
                        interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 523 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 524 IRQ_TYPE_LEVEL_HIGH>,
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie2a_port0: pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie2a_phy: phy@1c24000 {
                        interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               usb_2: usb@a4f8800 {
+                       compatible = "qcom,sc8280xp-dwc3-mp", "qcom,dwc3";
+                       reg = <0 0x0a4f8800 0 0x400>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       clocks = <&gcc GCC_CFG_NOC_USB3_MP_AXI_CLK>,
+                                <&gcc GCC_USB30_MP_MASTER_CLK>,
+                                <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>,
+                                <&gcc GCC_USB30_MP_SLEEP_CLK>,
+                                <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+                                <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+                                <&gcc GCC_AGGRE_USB_NOC_NORTH_AXI_CLK>,
+                                <&gcc GCC_AGGRE_USB_NOC_SOUTH_AXI_CLK>,
+                                <&gcc GCC_SYS_NOC_USB_AXI_CLK>;
+                       clock-names = "cfg_noc", "core", "iface", "sleep", "mock_utmi",
+                                     "noc_aggr", "noc_aggr_north", "noc_aggr_south", "noc_sys";
+
+                       assigned-clocks = <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB30_MP_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <200000000>;
+
+                       interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 857 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 859 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&pdc 127 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 126 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 129 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 128 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 131 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 130 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 133 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 132 IRQ_TYPE_EDGE_BOTH>,
+                                             <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+
+                       interrupt-names = "pwr_event_1", "pwr_event_2",
+                                         "pwr_event_3", "pwr_event_4",
+                                         "hs_phy_1",    "hs_phy_2",
+                                         "hs_phy_3",    "hs_phy_4",
+                                         "dp_hs_phy_1", "dm_hs_phy_1",
+                                         "dp_hs_phy_2", "dm_hs_phy_2",
+                                         "dp_hs_phy_3", "dm_hs_phy_3",
+                                         "dp_hs_phy_4", "dm_hs_phy_4",
+                                         "ss_phy_1",    "ss_phy_2";
+
+                       power-domains = <&gcc USB30_MP_GDSC>;
+                       required-opps = <&rpmhpd_opp_nom>;
+
+                       resets = <&gcc GCC_USB30_MP_BCR>;
+
+                       interconnects = <&aggre1_noc MASTER_USB3_MP 0 &mc_virt SLAVE_EBI1 0>,
+                                       <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_MP 0>;
+                       interconnect-names = "usb-ddr", "apps-usb";
+
+                       wakeup-source;
+
+                       status = "disabled";
+
+                       usb_2_dwc3: usb@a400000 {
+                               compatible = "snps,dwc3";
+                               reg = <0 0x0a400000 0 0xcd00>;
+                               interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                               iommus = <&apps_smmu 0x800 0x0>;
+                               phys = <&usb_2_hsphy0>, <&usb_2_qmpphy0>,
+                                      <&usb_2_hsphy1>, <&usb_2_qmpphy1>,
+                                      <&usb_2_hsphy2>,
+                                      <&usb_2_hsphy3>;
+                               phy-names = "usb2-0", "usb3-0",
+                                           "usb2-1", "usb3-1",
+                                           "usb2-2",
+                                           "usb2-3";
+                               dr_mode = "host";
+                       };
+               };
+
                usb_0: usb@a6f8800 {
                        compatible = "qcom,sc8280xp-dwc3", "qcom,dwc3";
                        reg = <0 0x0a6f8800 0 0x400>;
                        assigned-clock-rates = <19200000>, <200000000>;
 
                        interrupts-extended = <&intc GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
                                              <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
                                              <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
                                              <&pdc 138 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "pwr_event",
+                                         "hs_phy_irq",
                                          "dp_hs_phy_irq",
                                          "dm_hs_phy_irq",
                                          "ss_phy_irq";
                        assigned-clock-rates = <19200000>, <200000000>;
 
                        interrupts-extended = <&intc GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 790 IRQ_TYPE_LEVEL_HIGH>,
                                              <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
                                              <&pdc 13 IRQ_TYPE_EDGE_BOTH>,
                                              <&pdc 136 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "pwr_event",
+                                         "hs_phy_irq",
                                          "dp_hs_phy_irq",
                                          "dm_hs_phy_irq",
                                          "ss_phy_irq";
                        #thermal-sensor-cells = <1>;
                };
 
+               restart@c264000 {
+                       compatible = "qcom,pshold";
+                       reg = <0 0x0c264000 0 0x4>;
+               };
+
                tsens1: thermal-sensor@c265000 {
                        compatible = "qcom,sc8280xp-tsens", "qcom,tsens-v2";
                        reg = <0 0x0c265000 0 0x1ff>, /* TM */
                        #size-cells = <2>;
                        ranges;
 
-                       msi-controller@17a40000 {
+                       its: msi-controller@17a40000 {
                                compatible = "arm,gic-v3-its";
                                reg = <0 0x17a40000 0 0x20000>;
                                msi-controller;
                              <0 0x18592000 0 0x1000>;
                        reg-names = "freq-domain0", "freq-domain1";
 
+                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "dcvsh-irq-0",
+                                         "dcvsh-irq-1";
+
                        clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
                        clock-names = "xo", "alternate";
 
index 819a5f8825e783daef1a64d4e460cb3bd7e5aa1a..a4b722e0fc1e1216dcb55908040d6238406e80b3 100644 (file)
@@ -90,6 +90,8 @@
 
        gpio-keys {
                compatible = "gpio-keys";
+               pinctrl-0 = <&gpio_keys_default>;
+               pinctrl-names = "default";
 
                key-camera-focus {
                        label = "Camera Focus";
                bias-disable;
        };
 
+       gpio_keys_default: gpio-keys-default-state {
+               pins = "gpio64", "gpio113";
+               function = "gpio";
+               drive-strength = <2>;
+               bias-pull-up;
+       };
+
        imx300_vana_default: imx300-vana-default-state {
                pins = "gpio50";
                function = "gpio";
index 057579ae30138d343477e8cc4db5ccca46d3b128..e2708c74e95afd2f199306a9e868f2bbd6f26de3 100644 (file)
        };
 };
 
+&pmi632_typec {
+       status = "okay";
+
+       connector {
+               compatible = "usb-c-connector";
+
+               power-role = "dual";
+               data-role = "dual";
+               self-powered;
+
+               typec-power-opmode = "default";
+               pd-disable;
+
+               port {
+                       pmi632_hs_in: endpoint {
+                               remote-endpoint = <&usb_dwc3_hs>;
+                       };
+               };
+       };
+};
+
+&pmi632_vbus {
+       regulator-min-microamp = <500000>;
+       regulator-max-microamp = <1000000>;
+       status = "okay";
+};
+
 &sdhc_1 {
        status = "okay";
        vmmc-supply = <&pm8953_l8>;
        status = "okay";
 };
 
-&usb3_dwc3 {
-       dr_mode = "peripheral";
+&usb_dwc3_hs {
+       remote-endpoint = <&pmi632_hs_in>;
 };
 
 &wcnss {
index 32a7bd59e1ece195f486e40f72755daf4cdc32ec..176b0119fe6d45d7d3fa584f1825f4e4e681c2e7 100644 (file)
        };
 };
 
+&mdss {
+       status = "okay";
+};
+
+&mdss_dsi0 {
+       vdda-supply = <&vreg_l1a_1p225>;
+       status = "okay";
+
+       panel@0 {
+               compatible = "samsung,s6e3fa7-ams559nk06";
+               reg = <0>;
+
+               reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&panel_default>;
+
+               power-supply = <&vreg_l6b_3p3>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&mdss_dsi0_out>;
+                       };
+               };
+       };
+};
+
+&mdss_dsi0_out {
+       remote-endpoint = <&panel_in>;
+       data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+       vdds-supply = <&vreg_l1b_0p925>;
+       status = "okay";
+};
+
+&mdss_mdp {
+       status = "okay";
+};
+
 &pm660l_gpios {
        vol_up_pin: vol-up-state {
                pins = "gpio7";
 &tlmm {
        gpio-reserved-ranges = <0 4>, <81 4>;
 
+       panel_default: panel-default-state {
+               te-pins {
+                       pins = "gpio10";
+                       function = "mdp_vsync";
+                       drive-strength = <2>;
+                       bias-pull-down;
+               };
+
+               reset-pins {
+                       pins = "gpio75";
+                       function = "gpio";
+                       drive-strength = <8>;
+                       bias-disable;
+               };
+
+               mode-pins {
+                       pins = "gpio76";
+                       function = "gpio";
+                       drive-strength = <8>;
+                       bias-disable;
+               };
+       };
+
        touchscreen_default: ts-default-state {
                ts-reset-pins {
                        pins = "gpio99";
index 1f517328199b908655a5eed5c350641edd06ae1a..9a6d3d0c0ee43af337728546626ec70ce47b9ec6 100644 (file)
 
                gpio = <&tlmm 90 GPIO_ACTIVE_HIGH>;
                enable-active-high;
+               /*
+                * FIXME: this regulator is responsible for VBUS on the left USB
+                * port. Keep it always on until we can correctly model this
+                * relationship.
+                */
+               regulator-always-on;
 
                pinctrl-names = "default";
                pinctrl-0 = <&pcie0_pwren_state>;
index 2f20be99ee7e13dd18802c31d8302f4f5fbc3cff..10de2bd46ffcc659198ad3e70badd82a3a89ad3d 100644 (file)
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0a000 {
index 7dbdf8ca6de685bc7c0605619022eff149cc8c7c..da1704061d58c7440ba13460fdef58aa3b2f4afb 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a55-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
        };
 
                hwlocks = <&tcsr_mutex 3>;
        };
 
-       soc: soc {
+       soc: soc@0 {
                compatible = "simple-bus";
                #address-cells = <2>;
                #size-cells = <2>;
index 0be053555602c0d3e1bd52888c05e841bb4de9ae..84ff20a96c838b52d8e5d54f97e3792de3f8fd99 100644 (file)
                        status = "disabled";
                };
 
+               cryptobam: dma-controller@1dc4000 {
+                       compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
+                       reg = <0 0x01dc4000 0 0x24000>;
+                       interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       qcom,ee = <0>;
+                       qcom,controlled-remotely;
+                       num-channels = <16>;
+                       qcom,num-ees = <4>;
+                       iommus = <&apps_smmu 0x426 0x11>,
+                                <&apps_smmu 0x432 0x0>,
+                                <&apps_smmu 0x436 0x11>,
+                                <&apps_smmu 0x438 0x1>,
+                                <&apps_smmu 0x43f 0x0>;
+               };
+
+               crypto: crypto@1dfa000 {
+                       compatible = "qcom,sm6350-qce", "qcom,sm8150-qce", "qcom,qce";
+                       reg = <0 0x01dfa000 0 0x6000>;
+                       dmas = <&cryptobam 4>, <&cryptobam 5>;
+                       dma-names = "rx", "tx";
+                       iommus = <&apps_smmu 0x426 0x11>,
+                                <&apps_smmu 0x432 0x0>,
+                                <&apps_smmu 0x436 0x11>,
+                                <&apps_smmu 0x438 0x1>,
+                                <&apps_smmu 0x43f 0x0>;
+                       interconnects = <&aggre2_noc MASTER_CRYPTO_CORE_0 QCOM_ICC_TAG_ALWAYS
+                                        &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "memory";
+               };
+
                ipa: ipa@1e40000 {
                        compatible = "qcom,sm6350-ipa";
 
                                                        remote-endpoint = <&mdss_dsi0_in>;
                                                };
                                        };
+
+                                       port@2 {
+                                               reg = <2>;
+
+                                               dpu_intf0_out: endpoint {
+                                                       remote-endpoint = <&mdss_dp_in>;
+                                               };
+                                       };
                                };
 
                                mdp_opp_table: opp-table {
                                };
                        };
 
+                       mdss_dp: displayport-controller@ae90000 {
+                               compatible = "qcom,sm6350-dp", "qcom,sm8350-dp";
+                               reg = <0 0xae90000 0 0x200>,
+                                     <0 0xae90200 0 0x200>,
+                                     <0 0xae90400 0 0x600>,
+                                     <0 0xae91000 0 0x400>,
+                                     <0 0xae91400 0 0x400>;
+                               interrupt-parent = <&mdss>;
+                               interrupts = <12>;
+                               clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+                                        <&dispcc DISP_CC_MDSS_DP_AUX_CLK>,
+                                        <&dispcc DISP_CC_MDSS_DP_LINK_CLK>,
+                                        <&dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+                                        <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK>;
+                               clock-names = "core_iface",
+                                             "core_aux",
+                                             "ctrl_link",
+                                             "ctrl_link_iface",
+                                             "stream_pixel";
+
+                               assigned-clocks = <&dispcc DISP_CC_MDSS_DP_LINK_CLK_SRC>,
+                                                 <&dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>;
+                               assigned-clock-parents = <&usb_1_qmpphy QMP_USB43DP_DP_LINK_CLK>,
+                                                        <&usb_1_qmpphy QMP_USB43DP_DP_VCO_DIV_CLK>;
+
+                               phys = <&usb_1_qmpphy QMP_USB43DP_DP_PHY>;
+                               phy-names = "dp";
+
+                               #sound-dai-cells = <0>;
+
+                               operating-points-v2 = <&dp_opp_table>;
+                               power-domains = <&rpmhpd SM6350_CX>;
+
+                               status = "disabled";
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               reg = <0>;
+
+                                               mdss_dp_in: endpoint {
+                                                       remote-endpoint = <&dpu_intf0_out>;
+                                               };
+                                       };
+
+                                       port@1 {
+                                               reg = <1>;
+
+                                               mdss_dp_out: endpoint {
+                                               };
+                                       };
+                               };
+
+                               dp_opp_table: opp-table {
+                                       compatible = "operating-points-v2";
+
+                                       opp-160000000 {
+                                               opp-hz = /bits/ 64 <160000000>;
+                                               required-opps = <&rpmhpd_opp_low_svs>;
+                                       };
+
+                                       opp-270000000 {
+                                               opp-hz = /bits/ 64 <270000000>;
+                                               required-opps = <&rpmhpd_opp_svs>;
+                                       };
+
+                                       opp-540000000 {
+                                               opp-hz = /bits/ 64 <540000000>;
+                                               required-opps = <&rpmhpd_opp_svs_l1>;
+                                       };
+
+                                       opp-810000000 {
+                                               opp-hz = /bits/ 64 <810000000>;
+                                               required-opps = <&rpmhpd_opp_nom>;
+                                       };
+                               };
+                       };
+
                        mdss_dsi0: dsi@ae94000 {
                                compatible = "qcom,sm6350-dsi-ctrl", "qcom,mdss-dsi-ctrl";
                                reg = <0 0x0ae94000 0 0x400>;
index de670b407ef1425f7de2d2aa822a574a3a7496e3..6cb6f503fdac95c7b0ff902c7662830b9d27efd8 100644 (file)
        firmware-name = "qcom/sm8150/cdsp.mbn";
 };
 
+&remoteproc_mpss {
+       firmware-name = "qcom/sm8150/modem.mbn";
+       status = "okay";
+};
+
 &remoteproc_slpi {
        status = "okay";
 
 &usb_2_dwc3 {
        dr_mode = "host";
 };
+
+&wifi {
+       status = "okay";
+
+       vdd-0.8-cx-mx-supply = <&vreg_l1a_0p75>;
+       vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+       vdd-1.3-rfa-supply = <&vreg_l2c_1p3>;
+       vdd-3.3-ch0-supply = <&vreg_l11c_3p3>;
+
+       qcom,ath10k-calibration-variant = "Qualcomm_sm8150hdk";
+};
index a35c0852b5a14cd8e2833986916bc24d096eefb0..ff22e434666023492f7528cc716f707ffcd91517 100644 (file)
                        pinctrl-0 = <&pcie0_default_state>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        pinctrl-0 = <&pcie1_default_state>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
index 6f54f50a70b0f8e0b0c81da5963e319858b6ddcd..41f117474872898aaeaab698ace0749f06f8743c 100644 (file)
        connector {
                compatible = "usb-c-connector";
 
-               power-role = "source";
+               op-sink-microwatt = <10000000>;
+               power-role = "dual";
                data-role = "dual";
                self-powered;
 
                                         PDO_FIXED_USB_COMM |
                                         PDO_FIXED_DATA_SWAP)>;
 
+               sink-pdos = <PDO_FIXED(5000, 3000,
+                                      PDO_FIXED_DUAL_ROLE |
+                                      PDO_FIXED_USB_COMM |
+                                      PDO_FIXED_DATA_SWAP)
+                                      PDO_VAR(5000, 12000, 5000)>;
+
                ports {
                        #address-cells = <1>;
                        #size-cells = <0>;
 };
 
 &pm8150b_vbus {
+       regulator-min-microamp = <500000>;
+       regulator-max-microamp = <3000000>;
        status = "okay";
 };
 
index 7f2333c9d17d6d74ee3fe33a017e2fa03bcb3683..8ccade628f1f471bb41495b55b4708aae76d75b2 100644 (file)
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie2_phy: phy@1c16000 {
index b43d264ed42b1c78e40fb7930501f49ae2af1a14..4c25ab2f5670ef51f212280bb7a503aae9803a78 100644 (file)
@@ -42,6 +42,7 @@
                compatible = "qcom,sm8350-pmic-glink", "qcom,pmic-glink";
                #address-cells = <1>;
                #size-cells = <0>;
+               orientation-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>;
 
                connector@0 {
                        compatible = "usb-c-connector";
index a5e7dbbd8c6c5ee1d9c46233f8ef034957b7984f..f7c4700f00c36c19ed287eaa2c6ee1188ca57121 100644 (file)
@@ -12,6 +12,7 @@
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/firmware/qcom,scm.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
 #include <dt-bindings/interconnect/qcom,sm8350.h>
 #include <dt-bindings/mailbox/qcom-ipcc.h>
 #include <dt-bindings/phy/phy-qcom-qmp.h>
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                                <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
                                <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
                                <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+                       interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
+                                        &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+                                       <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+                                        &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ALWAYS>;
+                       interconnect-names = "ufs-ddr", "cpu-ufs";
                        freq-table-hz =
                                <75000000 300000000>,
                                <0 0>,
index 0786cff07b8920f36576c9007f261d32c04fa08a..3be46b56c723d4e743a27bda3ac834efdd75f01f 100644 (file)
@@ -95,6 +95,7 @@
                compatible = "qcom,sm8450-pmic-glink", "qcom,pmic-glink";
                #address-cells = <1>;
                #size-cells = <0>;
+               orientation-gpios = <&tlmm 91 GPIO_ACTIVE_HIGH>;
 
                connector@0 {
                        compatible = "usb-c-connector";
index c7d05945aa5192632253b421a3c3e06b25f8998c..7b62ead68e773209d11bc481880f6d78d018ae56 100644 (file)
        vdda-pll-supply = <&vreg_l5b_0p88>;
        vdda18-supply = <&vreg_l1c_1p8>;
        vdda33-supply = <&vreg_l2b_3p07>;
+       qcom,squelch-detector-bp = <(-2090)>;
+       qcom,hs-disconnect-bp = <1743>;
+       qcom,pre-emphasis-amplitude-bp = <40000>;
+       qcom,pre-emphasis-duration-bp = <20000>;
+       qcom,hs-amplitude-bp = <2000>;
+       qcom,hs-output-impedance-micro-ohms = <2600000>;
+       qcom,hs-crossover-voltage-microvolt = <(-31000)>;
+       qcom,hs-rise-fall-time-bp = <(-4100)>;
 };
 
 &usb_1_qmpphy {
index 024d2653cc3075126a59da6f099c5a14b18bc8d6..616461fcbab99f264f05be9cd7cdee789809d15e 100644 (file)
                        pinctrl-0 = <&pcie0_default_state>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        pinctrl-0 = <&pcie1_default_state>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                                        compatible = "qcom,fastrpc";
                                        qcom,glink-channels = "fastrpcglink-apps-dsp";
                                        label = "sdsp";
+                                       qcom,non-secure-domain;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                        compatible = "qcom,fastrpc";
                                        qcom,glink-channels = "fastrpcglink-apps-dsp";
                                        label = "adsp";
+                                       qcom,non-secure-domain;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                        compatible = "qcom,fastrpc";
                                        qcom,glink-channels = "fastrpcglink-apps-dsp";
                                        label = "cdsp";
+                                       qcom,non-secure-domain;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
diff --git a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
new file mode 100644 (file)
index 0000000..85e0d3d
--- /dev/null
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/sound/cs35l45.h>
+#include "sm8550.dtsi"
+#include "pm8010.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+/* TODO: Only one SID of PMR735D seems accessible? */
+
+/delete-node/ &hwfence_shbuf;
+/delete-node/ &mpss_mem;
+/delete-node/ &rmtfs_mem;
+/ {
+       model = "Sony Xperia 1 V";
+       compatible = "sony,pdx234", "qcom,sm8550";
+       chassis-type = "handset";
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c4 = &i2c4;
+               i2c10 = &i2c10;
+               i2c11 = &i2c11;
+               i2c16 = &i2c_hub_2;
+               serial0 = &uart7;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               label = "gpio-keys";
+
+               pinctrl-0 = <&focus_n &snapshot_n &vol_down_n>;
+               pinctrl-names = "default";
+
+               key-camera-focus {
+                       label = "Camera Focus";
+                       linux,code = <KEY_CAMERA_FOCUS>;
+                       gpios = <&pm8550b_gpios 8 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <15>;
+                       linux,can-disable;
+                       wakeup-source;
+               };
+
+               key-camera-snapshot {
+                       label = "Camera Snapshot";
+                       gpios = <&pm8550b_gpios 7 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_CAMERA>;
+                       debounce-interval = <15>;
+                       linux,can-disable;
+                       wakeup-source;
+               };
+
+               key-volume-down {
+                       label = "Volume Down";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <15>;
+                       linux,can-disable;
+                       wakeup-source;
+               };
+       };
+
+       pmic-glink {
+               compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
+               orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               connector@0 {
+                       compatible = "usb-c-connector";
+                       reg = <0>;
+                       power-role = "dual";
+                       data-role = "dual";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       pmic_glink_hs_in: endpoint {
+                                               remote-endpoint = <&usb_1_dwc3_hs>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       pmic_glink_ss_in: endpoint {
+                                               remote-endpoint = <&usb_dp_qmpphy_out>;
+                                       };
+                               };
+                       };
+               };
+       };
+
+       reserved-memory {
+               mpss_mem: mpss-region@89800000 {
+                       reg = <0x0 0x89800000 0x0 0x10800000>;
+                       no-map;
+               };
+
+               splash@b8000000 {
+                       reg = <0x0 0xb8000000 0x0 0x2b00000>;
+                       no-map;
+               };
+
+               hwfence_shbuf: hwfence-shbuf-region@e6440000 {
+                       reg = <0x0 0xe6440000 0x0 0x2dd000>;
+                       no-map;
+               };
+
+               rmtfs_mem: memory@f8b00000 {
+                       compatible = "qcom,rmtfs-mem";
+                       reg = <0x0 0xf8b00000 0x0 0x280000>;
+                       no-map;
+
+                       qcom,client-id = <1>;
+                       qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>;
+               };
+
+               ramoops@ffd00000 {
+                       compatible = "ramoops";
+                       reg = <0x0 0xffd00000 0x0 0xc0000>;
+                       console-size = <0x40000>;
+                       record-size = <0x1000>;
+                       pmsg-size = <0x40000>;
+                       ecc-size = <16>;
+               };
+
+               rdtag-store-region@ffdc0000 {
+                       reg = <0x0 0xffdc0000 0x0 0x40000>;
+                       no-map;
+               };
+       };
+
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-min-microvolt = <3700000>;
+               regulator-max-microvolt = <3700000>;
+
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&apps_rsc {
+       regulators-0 {
+               compatible = "qcom,pm8550-rpmh-regulators";
+               qcom,pmic-id = "b";
+
+               pm8550_bob1: bob1 {
+                       regulator-name = "pm8550_bob1";
+                       regulator-min-microvolt = <3416000>;
+                       regulator-max-microvolt = <3960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               /* TODO: bob2 @ 2.704-3.008V doesn't fall into the vreg driver constraints */
+
+               pm8550_l1: ldo1 {
+                       regulator-name = "pm8550_l1";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l2: ldo2 {
+                       regulator-name = "pm8550_l2";
+                       regulator-min-microvolt = <3008000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               /* L4 exists in cmd-db, but the board seems to crash on access */
+
+               pm8550_l5: ldo5 {
+                       regulator-name = "pm8550_l5";
+                       regulator-min-microvolt = <3104000>;
+                       regulator-max-microvolt = <3104000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l6: ldo6 {
+                       regulator-name = "pm8550_l6";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l7: ldo7 {
+                       regulator-name = "pm8550_l7";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l8: ldo8 {
+                       regulator-name = "pm8550_l8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l9: ldo9 {
+                       regulator-name = "pm8550_l9";
+                       regulator-min-microvolt = <2960000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l10: ldo10 {
+                       regulator-name = "pm8550_l10";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l11: ldo11 {
+                       regulator-name = "pm8550_l11";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1504000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l12: ldo12 {
+                       regulator-name = "pm8550_l12";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l13: ldo13 {
+                       regulator-name = "pm8550_l13";
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l14: ldo14 {
+                       regulator-name = "pm8550_l14";
+                       regulator-min-microvolt = <3304000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l15: ldo15 {
+                       regulator-name = "pm8550_l15";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l16: ldo16 {
+                       regulator-name = "pm8550_l16";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550_l17: ldo17 {
+                       regulator-name = "pm8550_l17";
+                       regulator-min-microvolt = <2504000>;
+                       regulator-max-microvolt = <2504000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       regulators-1 {
+               compatible = "qcom,pm8550vs-rpmh-regulators";
+               qcom,pmic-id = "c";
+
+               pm8550vs_0_l1: ldo1 {
+                       regulator-name = "pm8550vs_0_l1";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_0_l3: ldo3 {
+                       regulator-name = "pm8550vs_0_l3";
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       regulators-2 {
+               compatible = "qcom,pm8550vs-rpmh-regulators";
+               qcom,pmic-id = "d";
+
+               pm8550vs_1_l1: ldo1 {
+                       regulator-name = "pm8550vs_1_l1";
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <920000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               /* L3 exists in cmd-db, but the board seems to crash on access */
+       };
+
+       regulators-3 {
+               compatible = "qcom,pm8550vs-rpmh-regulators";
+               qcom,pmic-id = "e";
+
+               pm8550vs_2_s4: smps4 {
+                       regulator-name = "pm8550vs_2_s4";
+                       regulator-min-microvolt = <904000>;
+                       regulator-max-microvolt = <984000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_2_s5: smps5 {
+                       regulator-name = "pm8550vs_2_s5";
+                       regulator-min-microvolt = <1010000>;
+                       regulator-max-microvolt = <1120000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_2_l1: ldo1 {
+                       regulator-name = "pm8550vs_2_l1";
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_2_l2: ldo2 {
+                       regulator-name = "pm8550vs_2_l2";
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <968000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_2_l3: ldo3 {
+                       regulator-name = "pm8550vs_2_l3";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       regulators-4 {
+               compatible = "qcom,pm8550ve-rpmh-regulators";
+               qcom,pmic-id = "f";
+
+               pm8550ve_s4: smps4 {
+                       regulator-name = "pm8550ve_s4";
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <700000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550ve_l1: ldo1 {
+                       regulator-name = "pm8550ve_l1";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550ve_l2: ldo2 {
+                       regulator-name = "pm8550ve_l2";
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550ve_l3: ldo3 {
+                       regulator-name = "pm8550ve_l3";
+                       regulator-min-microvolt = <912000>;
+                       regulator-max-microvolt = <912000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       regulators-5 {
+               compatible = "qcom,pm8550vs-rpmh-regulators";
+               qcom,pmic-id = "g";
+
+               pm8550vs_3_s1: smps1 {
+                       regulator-name = "pm8550vs_3_s1";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1300000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_s2: smps2 {
+                       regulator-name = "pm8550vs_3_s2";
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1036000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_s3: smps3 {
+                       regulator-name = "pm8550vs_3_s3";
+                       regulator-min-microvolt = <300000>;
+                       regulator-max-microvolt = <1004000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_s4: smps4 {
+                       regulator-name = "pm8550vs_3_s4";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1352000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_s5: smps5 {
+                       regulator-name = "pm8550vs_3_s5";
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1004000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_s6: smps6 {
+                       regulator-name = "pm8550vs_3_s6";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2000000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_l1: ldo1 {
+                       regulator-name = "pm8550vs_3_l1";
+                       regulator-min-microvolt = <1144000>;
+                       regulator-max-microvolt = <1256000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_l2: ldo2 {
+                       regulator-name = "pm8550vs_3_l2";
+                       regulator-min-microvolt = <1104000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               pm8550vs_3_l3: ldo3 {
+                       regulator-name = "pm8550vs_3_l3";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       /* TODO: Unknown PMIC @ k, l, PM8010 @ m, n */
+};
+
+&gpi_dma1 {
+       status = "okay";
+};
+
+&gpi_dma2 {
+       status = "okay";
+};
+
+&i2c_hub_2 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       pmic@75 {
+               compatible = "dlg,slg51000";
+               reg = <0x75>;
+               dlg,cs-gpios = <&pm8550vs_g_gpios 4 GPIO_ACTIVE_HIGH>;
+
+               pinctrl-0 = <&cam_pwr_a_cs>;
+               pinctrl-names = "default";
+
+               regulators {
+                       slg51000_a_ldo1: ldo1 {
+                               regulator-name = "slg51000_a_ldo1";
+                               regulator-min-microvolt = <2400000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       slg51000_a_ldo2: ldo2 {
+                               regulator-name = "slg51000_a_ldo2";
+                               regulator-min-microvolt = <2400000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+
+                       slg51000_a_ldo3: ldo3 {
+                               regulator-name = "slg51000_a_ldo3";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3750000>;
+                       };
+
+                       slg51000_a_ldo4: ldo4 {
+                               regulator-name = "slg51000_a_ldo4";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3750000>;
+                       };
+
+                       slg51000_a_ldo5: ldo5 {
+                               regulator-name = "slg51000_a_ldo5";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       slg51000_a_ldo6: ldo6 {
+                               regulator-name = "slg51000_a_ldo6";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1200000>;
+                       };
+
+                       slg51000_a_ldo7: ldo7 {
+                               regulator-name = "slg51000_a_ldo7";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3750000>;
+                       };
+               };
+       };
+};
+
+&i2c_master_hub_0 {
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <1000000>;
+       status = "okay";
+
+       /* NXP NFC @ 28 */
+};
+
+&i2c4 {
+       clock-frequency = <400000>;
+       status = "okay";
+
+       /* LX Semi SW82907 touchscreen @ 28 */
+};
+
+&i2c10 {
+       clock-frequency = <1000000>;
+       status = "okay";
+
+       /* Cirrus Logic CS40L25A boosted haptics driver @ 40 */
+};
+
+&i2c11 {
+       clock-frequency = <1000000>;
+       status = "okay";
+
+       cs35l41_l: speaker-amp@30 {
+               compatible = "cirrus,cs35l45";
+               reg = <0x30>;
+               interrupts-extended = <&tlmm 182 IRQ_TYPE_LEVEL_LOW>;
+               reset-gpios = <&tlmm 183 GPIO_ACTIVE_HIGH>;
+               cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED | CS35L45_ASP_TX_HIZ_DISABLED)>;
+               #sound-dai-cells = <1>;
+
+               cirrus,gpio-ctrl2 {
+                       gpio-ctrl = <0x2>;
+               };
+       };
+
+       cs35l41_r: speaker-amp@31 {
+               compatible = "cirrus,cs35l45";
+               reg = <0x31>;
+               interrupts-extended = <&tlmm 182 IRQ_TYPE_LEVEL_LOW>;
+               reset-gpios = <&tlmm 183 GPIO_ACTIVE_HIGH>;
+               cirrus,asp-sdout-hiz-ctrl = <(CS35L45_ASP_TX_HIZ_UNUSED | CS35L45_ASP_TX_HIZ_DISABLED)>;
+               #sound-dai-cells = <1>;
+
+               cirrus,gpio-ctrl2 {
+                       gpio-ctrl = <0x2>;
+               };
+       };
+};
+
+&pcie0 {
+       wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+       perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+
+       pinctrl-0 = <&pcie0_default_state>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
+
+&pcie0_phy {
+       vdda-phy-supply = <&pm8550vs_2_l1>;
+       vdda-pll-supply = <&pm8550vs_2_l3>;
+
+       status = "okay";
+};
+
+&pm8550_flash {
+       status = "okay";
+
+       led-0 {
+               function = LED_FUNCTION_FLASH;
+               color = <LED_COLOR_ID_WHITE>;
+               led-sources = <1>, <4>;
+               led-max-microamp = <500000>;
+               flash-max-microamp = <1000000>;
+               flash-max-timeout-us = <1280000>;
+               function-enumerator = <0>;
+       };
+
+       led-1 {
+               function = LED_FUNCTION_FLASH;
+               color = <LED_COLOR_ID_YELLOW>;
+               led-sources = <2>, <3>;
+               led-max-microamp = <500000>;
+               flash-max-microamp = <1000000>;
+               flash-max-timeout-us = <1280000>;
+               function-enumerator = <1>;
+       };
+};
+
+&pm8550_gpios {
+       vol_down_n: volume-down-n-state {
+               pins = "gpio6";
+               function = "normal";
+               power-source = <1>;
+               bias-pull-up;
+               input-enable;
+       };
+
+       sdc2_card_det_n: sd-card-det-n-state {
+               pins = "gpio12";
+               function = "normal";
+               power-source = <1>;
+               bias-pull-down;
+               output-disable;
+               input-enable;
+       };
+};
+
+&pm8550b_gpios {
+       snapshot_n: snapshot-n-state {
+               pins = "gpio7";
+               function = "normal";
+               power-source = <1>;
+               bias-pull-up;
+               input-enable;
+       };
+
+       focus_n: focus-n-state {
+               pins = "gpio8";
+               function = "normal";
+               power-source = <1>;
+               bias-pull-up;
+               input-enable;
+       };
+};
+
+&pm8550vs_g_gpios {
+       cam_pwr_a_cs: cam-pwr-a-cs-state {
+               pins = "gpio4";
+               function = "normal";
+               power-source = <0x01>;
+               drive-push-pull;
+               output-low;
+               qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>;
+       };
+};
+
+&pm8550b_eusb2_repeater {
+       qcom,tune-usb2-disc-thres = /bits/ 8 <0x6>;
+       qcom,tune-usb2-amplitude = /bits/ 8 <0xf>;
+       qcom,tune-usb2-preem = /bits/ 8 <0x7>;
+       vdd18-supply = <&pm8550_l15>;
+       vdd3-supply = <&pm8550_l5>;
+};
+
+&pon_pwrkey {
+       status = "okay";
+};
+
+&pon_resin {
+       linux,code = <KEY_VOLUMEUP>;
+       status = "okay";
+};
+
+&qupv3_id_0 {
+       status = "okay";
+};
+
+&qupv3_id_1 {
+       status = "okay";
+};
+
+&remoteproc_adsp {
+       firmware-name = "qcom/sm8550/Sony/yodo/adsp.mbn",
+                       "qcom/sm8550/Sony/yodo/adsp_dtb.mbn";
+       status = "okay";
+};
+
+&remoteproc_cdsp {
+       firmware-name = "qcom/sm8550/Sony/yodo/cdsp.mbn",
+                       "qcom/sm8550/Sony/yodo/cdsp_dtb.mbn";
+       status = "okay";
+};
+
+&sdhc_2 {
+       cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_HIGH>;
+       pinctrl-0 = <&sdc2_default &sdc2_card_det_n>;
+       pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>;
+       pinctrl-names = "default", "sleep";
+       vmmc-supply = <&pm8550_l9>;
+       vqmmc-supply = <&pm8550_l8>;
+       no-sdio;
+       no-mmc;
+       status = "okay";
+};
+
+&sleep_clk {
+       clock-frequency = <32000>;
+};
+
+&tlmm {
+       gpio-reserved-ranges = <32 8>;
+};
+
+&uart7 {
+       status = "okay";
+};
+
+&usb_1 {
+       status = "okay";
+};
+
+&usb_1_dwc3 {
+       dr_mode = "otg";
+       usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+       remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+       remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
+};
+
+&usb_1_hsphy {
+       vdd-supply = <&pm8550vs_2_l1>;
+       vdda12-supply = <&pm8550vs_2_l3>;
+       phys = <&pm8550b_eusb2_repeater>;
+
+       status = "okay";
+};
+
+&usb_dp_qmpphy {
+       vdda-phy-supply = <&pm8550vs_2_l3>;
+       vdda-pll-supply = <&pm8550ve_l3>;
+       orientation-switch;
+
+       status = "okay";
+};
+
+&usb_dp_qmpphy_out {
+       remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+       remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
+&xo_board {
+       clock-frequency = <76800000>;
+};
index 3348bc06db488a77e4dd17dff687ffbcfa1cfced..bc5aeb05ffc3dbb0887a95b693a501896523790f 100644 (file)
                        dma-channels = <12>;
                        dma-channel-mask = <0x3e>;
                        iommus = <&apps_smmu 0x436 0>;
+                       dma-coherent;
                        status = "disabled";
                };
 
                        clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>,
                                 <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>;
                        iommus = <&apps_smmu 0x423 0>;
+                       dma-coherent;
                        #address-cells = <2>;
                        #size-cells = <2>;
                        status = "disabled";
                        dma-channels = <12>;
                        dma-channel-mask = <0x1e>;
                        iommus = <&apps_smmu 0xb6 0>;
+                       dma-coherent;
                        status = "disabled";
                };
 
                        iommus = <&apps_smmu 0xa3 0>;
                        interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>;
                        interconnect-names = "qup-core";
+                       dma-coherent;
                        #address-cells = <2>;
                        #size-cells = <2>;
                        status = "disabled";
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                        phy-names = "pciephy";
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                                reg = <0x0 0x0a600000 0x0 0xcd00>;
                                interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
                                iommus = <&apps_smmu 0x40 0x0>;
-                               snps,dis_u2_susphy_quirk;
-                               snps,dis_enblslpm_quirk;
-                               snps,usb3_lpm_capable;
                                phys = <&usb_1_hsphy>,
                                       <&usb_dp_qmpphy QMP_USB43DP_USB3_PHY>;
                                phy-names = "usb2-phy", "usb3-phy";
+                               snps,hird-threshold = /bits/ 8 <0x0>;
+                               snps,usb2-gadget-lpm-disable;
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                               snps,dis-u1-entry-quirk;
+                               snps,dis-u2-entry-quirk;
+                               snps,is-utmi-l1-suspend;
+                               snps,usb3_lpm_capable;
+                               snps,usb2-lpm-disable;
+                               snps,has-lpm-erratum;
+                               tx-fifo-resize;
+                               dma-coherent;
 
                                ports {
                                        #address-cells = <1>;
                                     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>;
+                       dma-coherent;
                };
 
                intc: interrupt-controller@17100000 {
                                        compatible = "qcom,fastrpc";
                                        qcom,glink-channels = "fastrpcglink-apps-dsp";
                                        label = "adsp";
+                                       qcom,non-secure-domain;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                        compatible = "qcom,fastrpc";
                                        qcom,glink-channels = "fastrpcglink-apps-dsp";
                                        label = "cdsp";
+                                       qcom,non-secure-domain;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
index 4450273f96671b53896c48c26b19fc06c648beb6..d04ceaa73c2b1920260208cba48b3fc086cbaf10 100644 (file)
        status = "okay";
 };
 
-&mdss_mdp {
-       status = "okay";
-};
-
 &pcie_1_phy_aux_clk {
        clock-frequency = <1000>;
 };
index b07cac2e5bc802ba667d054eb923b8b0e1bc0d46..4e94f7fe4d2d0430ece931c236b14ac3714f2fe7 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       status = "okay";
+
+       zap-shader {
+               firmware-name = "qcom/sm8650/gen70900_zap.mbn";
+       };
+};
+
 &lpass_tlmm {
        spkr_1_sd_n_active: spkr-1-sd-n-active-state {
                pins = "gpio21";
        remote-endpoint = <&usb_dp_qmpphy_dp_in>;
 };
 
-&mdss_mdp {
-       status = "okay";
-};
-
 &pcie_1_phy_aux_clk {
        clock-frequency = <1000>;
 };
index eb117866e59ff861bf8a41827a44429e172d6010..62a6e77730bc5d95582fac7354f2e46c205a7d58 100644 (file)
                        no-map;
                };
 
-               /* Merged aop_config, tme_crash_dump, tme_log and uefi_log regions */
+               /* Merged aop_config, tme_crash_dump, tme_log, uefi_log, and chipinfo regions */
                aop_tme_uefi_merged_mem: aop-tme-uefi-merged@81c80000 {
-                       reg = <0 0x81c80000 0 0x74000>;
+                       reg = <0 0x81c80000 0 0x75000>;
                        no-map;
                };
 
                        dma-coherent;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie0_phy: phy@1c06000 {
                                 <0x02000000 0 0x40300000 0 0x40300000 0 0x1fd00000>;
 
                        status = "disabled";
+
+                       pcie@0 {
+                               device_type = "pci";
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               bus-range = <0x01 0xff>;
+
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges;
+                       };
                };
 
                pcie1_phy: phy@1c0e000 {
                        #reset-cells = <1>;
                };
 
+               gpu: gpu@3d00000 {
+                       compatible = "qcom,adreno-43051401", "qcom,adreno";
+                       reg = <0x0 0x03d00000 0x0 0x40000>,
+                             <0x0 0x03d9e000 0x0 0x2000>,
+                             <0x0 0x03d61000 0x0 0x800>;
+                       reg-names = "kgsl_3d0_reg_memory",
+                                   "cx_mem",
+                                   "cx_dbgc";
+
+                       interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+
+                       iommus = <&adreno_smmu 0 0x0>,
+                                <&adreno_smmu 1 0x0>;
+
+                       operating-points-v2 = <&gpu_opp_table>;
+
+                       qcom,gmu = <&gmu>;
+
+                       status = "disabled";
+
+                       zap-shader {
+                               memory-region = <&gpu_micro_code_mem>;
+                       };
+
+                       /* Speedbin needs more work on A740+, keep only lower freqs */
+                       gpu_opp_table: opp-table {
+                               compatible = "operating-points-v2";
+
+                               opp-231000000 {
+                                       opp-hz = /bits/ 64 <231000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+                               };
+
+                               opp-310000000 {
+                                       opp-hz = /bits/ 64 <310000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+                               };
+
+                               opp-366000000 {
+                                       opp-hz = /bits/ 64 <366000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+                               };
+
+                               opp-422000000 {
+                                       opp-hz = /bits/ 64 <422000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+                               };
+
+                               opp-500000000 {
+                                       opp-hz = /bits/ 64 <500000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+                               };
+
+                               opp-578000000 {
+                                       opp-hz = /bits/ 64 <578000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+                               };
+
+                               opp-629000000 {
+                                       opp-hz = /bits/ 64 <629000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+                               };
+
+                               opp-680000000 {
+                                       opp-hz = /bits/ 64 <680000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+                               };
+
+                               opp-720000000 {
+                                       opp-hz = /bits/ 64 <720000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+                               };
+
+                               opp-770000000 {
+                                       opp-hz = /bits/ 64 <770000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+                               };
+
+                               opp-834000000 {
+                                       opp-hz = /bits/ 64 <834000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+                               };
+                       };
+               };
+
+               gmu: gmu@3d6a000 {
+                       compatible = "qcom,adreno-gmu-750.1", "qcom,adreno-gmu";
+                       reg = <0x0 0x03d6a000 0x0 0x35000>,
+                             <0x0 0x03d50000 0x0 0x10000>,
+                             <0x0 0x0b280000 0x0 0x10000>;
+                       reg-names = "gmu", "rscc", "gmu_pdc";
+
+                       interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hfi", "gmu";
+
+                       clocks = <&gpucc GPU_CC_AHB_CLK>,
+                                <&gpucc GPU_CC_CX_GMU_CLK>,
+                                <&gpucc GPU_CC_CXO_CLK>,
+                                <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+                                <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+                                <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+                                <&gpucc GPU_CC_DEMET_CLK>;
+                       clock-names = "ahb",
+                                     "gmu",
+                                     "cxo",
+                                     "axi",
+                                     "memnoc",
+                                     "hub",
+                                     "demet";
+
+                       power-domains = <&gpucc GPU_CX_GDSC>,
+                                       <&gpucc GPU_GX_GDSC>;
+                       power-domain-names = "cx",
+                                            "gx";
+
+                       iommus = <&adreno_smmu 5 0x0>;
+
+                       qcom,qmp = <&aoss_qmp>;
+
+                       operating-points-v2 = <&gmu_opp_table>;
+
+                       gmu_opp_table: opp-table {
+                               compatible = "operating-points-v2";
+
+                               opp-260000000 {
+                                       opp-hz = /bits/ 64 <260000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+                               };
+
+                               opp-625000000 {
+                                       opp-hz = /bits/ 64 <625000000>;
+                                       opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+                               };
+                       };
+               };
+
                gpucc: clock-controller@3d90000 {
                        compatible = "qcom,sm8650-gpucc";
                        reg = <0 0x03d90000 0 0xa000>;
                        #power-domain-cells = <1>;
                };
 
+               adreno_smmu: iommu@3da0000 {
+                       compatible = "qcom,sm8650-smmu-500", "qcom,adreno-smmu",
+                                    "qcom,smmu-500", "arm,mmu-500";
+                       reg = <0x0 0x03da0000 0x0 0x40000>;
+                       #iommu-cells = <2>;
+                       #global-interrupts = <1>;
+                       interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+                                <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+                                <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+                                <&gpucc GPU_CC_AHB_CLK>;
+                       clock-names = "hlos",
+                                     "bus",
+                                     "iface",
+                                     "ahb";
+                       power-domains = <&gpucc GPU_CX_GDSC>;
+                       dma-coherent;
+               };
+
                ipa: ipa@3f40000 {
                        compatible = "qcom,sm8650-ipa", "qcom,sm8550-ipa";
 
                        compatible = "qcom,sm8650-dwc3", "qcom,dwc3";
                        reg = <0 0x0a6f8800 0 0x400>;
 
-                       interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-                                             <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+                       interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                             <&pdc 14 IRQ_TYPE_EDGE_RISING>,
                                              <&pdc 15 IRQ_TYPE_EDGE_RISING>,
-                                             <&pdc 14 IRQ_TYPE_EDGE_RISING>;
-                       interrupt-names = "hs_phy_irq",
-                                         "ss_phy_irq",
+                                             <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "pwr_event",
+                                         "hs_phy_irq",
+                                         "dp_hs_phy_irq",
                                          "dm_hs_phy_irq",
-                                         "dp_hs_phy_irq";
+                                         "ss_phy_irq";
 
                        clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
                                 <&gcc GCC_USB30_PRIM_MASTER_CLK>,
 
                                        label = "adsp";
 
+                                       qcom,non-secure-domain;
+
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
 
                                        label = "cdsp";
 
+                                       qcom,non-secure-domain;
+
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                                         <&apps_smmu 0x19c8 0x0>;
                                                dma-coherent;
                                        };
+
+                                       /* note: secure cb9 in downstream */
+
+                                       compute-cb@10 {
+                                               compatible = "qcom,fastrpc-compute-cb";
+                                               reg = <12>;
+
+                                               iommus = <&apps_smmu 0x196c 0x0>,
+                                                        <&apps_smmu 0x0c0c 0x20>,
+                                                        <&apps_smmu 0x19cc 0x0>;
+                                               dma-coherent;
+                                       };
+
+                                       compute-cb@11 {
+                                               compatible = "qcom,fastrpc-compute-cb";
+                                               reg = <13>;
+
+                                               iommus = <&apps_smmu 0x196d 0x0>,
+                                                        <&apps_smmu 0x0c0d 0x20>,
+                                                        <&apps_smmu 0x19cd 0x0>;
+                                               dma-coherent;
+                                       };
+
+                                       compute-cb@12 {
+                                               compatible = "qcom,fastrpc-compute-cb";
+                                               reg = <14>;
+
+                                               iommus = <&apps_smmu 0x196e 0x0>,
+                                                        <&apps_smmu 0x0c0e 0x20>,
+                                                        <&apps_smmu 0x19ce 0x0>;
+                                               dma-coherent;
+                                       };
                                };
                        };
                };
index 6a0a54532e5feb494606f5da814cf1090256c725..c5c2895b37c7fb9915b737a1d7a95aaf7e86220e 100644 (file)
@@ -9,6 +9,7 @@
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 
 #include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
 
 / {
        model = "Qualcomm Technologies, Inc. X1E80100 CRD";
        compatible = "qcom,x1e80100-dp";
        /delete-property/ #sound-dai-cells;
 
-       data-lanes = <0 1 2 3>;
-
        status = "okay";
 
        aux-bus {
                port@1 {
                        reg = <1>;
                        mdss_dp3_out: endpoint {
+                               data-lanes = <0 1 2 3>;
+                               link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
                                remote-endpoint = <&edp_panel_in>;
                        };
                };
        status = "okay";
 };
 
+&smb2360_0_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l8b_3p0>;
+};
+
 &swr0 {
        status = "okay";
 
+       pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>;
+       pinctrl-names = "default";
+
        /* WSA8845, Left Woofer */
        left_woofer: speaker@0,0 {
                compatible = "sdw20217020400";
                reg = <0 0>;
-               pinctrl-0 = <&spkr_01_sd_n_active>;
-               pinctrl-names = "default";
-               powerdown-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
                #sound-dai-cells = <0>;
                sound-name-prefix = "WooferLeft";
                vdd-1p8-supply = <&vreg_l15b_1p8>;
        left_tweeter: speaker@0,1 {
                compatible = "sdw20217020400";
                reg = <0 1>;
-               /* pinctrl in left_woofer node because of sharing the GPIO*/
-               powerdown-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>;
                #sound-dai-cells = <0>;
                sound-name-prefix = "TwitterLeft";
                vdd-1p8-supply = <&vreg_l15b_1p8>;
 &swr3 {
        status = "okay";
 
+       pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>;
+       pinctrl-names = "default";
+
        /* WSA8845, Right Woofer */
        right_woofer: speaker@0,0 {
                compatible = "sdw20217020400";
                reg = <0 0>;
-               pinctrl-0 = <&spkr_23_sd_n_active>;
-               pinctrl-names = "default";
-               powerdown-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
                #sound-dai-cells = <0>;
                sound-name-prefix = "WooferRight";
                vdd-1p8-supply = <&vreg_l15b_1p8>;
        right_tweeter: speaker@0,1 {
                compatible = "sdw20217020400";
                reg = <0 1>;
-               /* pinctrl in right_woofer node because of sharing the GPIO*/
-               powerdown-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>;
                #sound-dai-cells = <0>;
                sound-name-prefix = "TwitterRight";
                vdd-1p8-supply = <&vreg_l15b_1p8>;
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_0_eusb2_repeater>;
+
        status = "okay";
 };
 
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_1_eusb2_repeater>;
+
        status = "okay";
 };
 
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_2_eusb2_repeater>;
+
        status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-pmics.dtsi
new file mode 100644 (file)
index 0000000..04301f7
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+};
+
+&spmi_bus1 {
+       smb2360_0: pmic@7 {
+               compatible = "qcom,smb2360", "qcom,spmi-pmic";
+               reg = <0x7 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               smb2360_0_eusb2_repeater: phy@fd00 {
+                       compatible = "qcom,smb2360-eusb2-repeater";
+                       reg = <0xfd00>;
+                       #phy-cells = <0>;
+               };
+       };
+
+       smb2360_1: pmic@a {
+               compatible = "qcom,smb2360", "qcom,spmi-pmic";
+               reg = <0xa SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               smb2360_1_eusb2_repeater: phy@fd00 {
+                       compatible = "qcom,smb2360-eusb2-repeater";
+                       reg = <0xfd00>;
+                       #phy-cells = <0>;
+               };
+       };
+
+       smb2360_2: pmic@b {
+               compatible = "qcom,smb2360", "qcom,spmi-pmic";
+               reg = <0xb SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               smb2360_2_eusb2_repeater: phy@fd00 {
+                       compatible = "qcom,smb2360-eusb2-repeater";
+                       reg = <0xfd00>;
+                       #phy-cells = <0>;
+               };
+       };
+};
index e76d29053d79bfa99274e0370872619f3c86e335..2061fbe7b75a9eb0ccbb291b5421eb126af0b897 100644 (file)
@@ -9,6 +9,7 @@
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 
 #include "x1e80100.dtsi"
+#include "x1e80100-pmics.dtsi"
 
 / {
        model = "Qualcomm Technologies, Inc. X1E80100 QCP";
        compatible = "qcom,x1e80100-dp";
        /delete-property/ #sound-dai-cells;
 
-       data-lanes = <0 1 2 3>;
-
        status = "okay";
 
        aux-bus {
                port@1 {
                        reg = <1>;
                        mdss_dp3_out: endpoint {
+                               data-lanes = <0 1 2 3>;
+                               link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+
                                remote-endpoint = <&edp_panel_in>;
                        };
                };
        status = "okay";
 };
 
+&smb2360_0_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l2b_3p0>;
+};
+
+&smb2360_1_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l14b_3p0>;
+};
+
+&smb2360_2_eusb2_repeater {
+       vdd18-supply = <&vreg_l3d_1p8>;
+       vdd3-supply = <&vreg_l8b_3p0>;
+};
+
 &tlmm {
        gpio-reserved-ranges = <33 3>, /* Unused */
                               <44 4>, /* SPI (TPM) */
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_0_eusb2_repeater>;
+
        status = "okay";
 };
 
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_1_eusb2_repeater>;
+
        status = "okay";
 };
 
        vdd-supply = <&vreg_l2e_0p8>;
        vdda12-supply = <&vreg_l3e_1p2>;
 
+       phys = <&smb2360_2_eusb2_repeater>;
+
        status = "okay";
 };
 
index 6b40082bac68ce92d87076f6ba7e0fd980dfb23c..5f90a0b3c0166d5bfe78f1a5e56f98abbff6bb61 100644 (file)
                        qcom,ports-hstart =             /bits/ 8 <0xff 0x03 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-hstop =              /bits/ 8 <0xff 0x06 0x0f 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-word-length =        /bits/ 8 <0x01 0x07 0x04 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
-                       qcom,ports-block-pack-mode =    /bits/ 8 <0xff 0x00 0x01 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+                       qcom,ports-block-pack-mode =    /bits/ 8 <0xff 0xff 0x01 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-block-group-count =  /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
                        qcom,ports-lane-control =       /bits/ 8 <0x01 0x00 0x00 0x00 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
 
 
                                                mdss_dp3_in: endpoint {
                                                        remote-endpoint = <&mdss_intf5_out>;
-
-                                                       link-frequencies = /bits/ 64 <8100000000>;
                                                };
                                        };
 
                        #clock-cells = <0>;
                };
 
+               spmi: arbiter@c400000 {
+                       compatible = "qcom,x1e80100-spmi-pmic-arb";
+                       reg = <0 0x0c400000 0 0x3000>,
+                             <0 0x0c500000 0 0x400000>,
+                             <0 0x0c440000 0 0x80000>;
+                       reg-names = "core", "chnls", "obsrvr";
+
+                       qcom,ee = <0>;
+                       qcom,channel = <0>;
+
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       spmi_bus0: spmi@c42d000 {
+                               reg = <0 0x0c42d000 0 0x4000>,
+                                     <0 0x0c4c0000 0 0x10000>;
+                               reg-names = "cnfg", "intr";
+
+                               interrupt-names = "periph_irq";
+                               interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <4>;
+
+                               #address-cells = <2>;
+                               #size-cells = <0>;
+                       };
+
+                       spmi_bus1: spmi@c432000 {
+                               reg = <0 0x0c432000 0 0x4000>,
+                                     <0 0x0c4d0000 0 0x10000>;
+                               reg-names = "cnfg", "intr";
+
+                               interrupt-names = "periph_irq";
+                               interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <4>;
+
+                               #address-cells = <2>;
+                               #size-cells = <0>;
+                       };
+               };
 
                tlmm: pinctrl@f100000 {
                        compatible = "qcom,x1e80100-tlmm";
index 39aefe66a7941ec6a35186a34fc98bddec036cf6..ba50e292bdbbf01ee7d9c5afa4b91761d2738d01 100644 (file)
@@ -48,7 +48,7 @@
                clock-output-names = "osc27M";
        };
 
-       soc {
+       soc@0 {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
index a3c10ceeb586e1891b17d95d65a160c09074e487..e8af39193e754fdbcb07aa92bcdfeedb94321769 100644 (file)
@@ -47,7 +47,7 @@
                clock-output-names = "osc27M";
        };
 
-       soc {
+       soc@0 {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
index 34802cc62983868bfdb68dbe1e0a9f4cda700935..3a7f6e35b7f74d0049afbc2077c8c881ab367929 100644 (file)
        };
 
        arm_pmu: pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a55-pmu";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
                interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>,
                        <&cpu3>, <&cpu4>, <&cpu5>;
                #clock-cells = <0>;
        };
 
-       soc {
+       soc@0 {
                compatible = "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
index 5f3e0e61d78d130cfb68f836d8a0800324382a2d..fbd214a1a63825983bebf171817fca7ab3bf287f 100644 (file)
@@ -62,6 +62,9 @@ dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb.dtb
 dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb-kf.dtb
 
 dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb
+dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function-expansion.dtbo
+r8a77970-eagle-function-expansion-dtbs := r8a77970-eagle.dtb r8a77970-eagle-function-expansion.dtbo
+dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle-function-expansion.dtb
 dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-v3msk.dtb
 
 dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso
new file mode 100644 (file)
index 0000000..3aa243c
--- /dev/null
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Eagle V3M Function expansion board.
+ *
+ * Copyright (C) 2024 Niklas Söderlund <niklas.soderlund@ragnatech.se>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       /* CN4 */
+       /* Eagle: SW18 set to OFF */
+       cvbs-in-cn4 {
+               compatible = "composite-video-connector";
+               label = "CVBS IN CN4";
+
+               port {
+                       cvbs_con: endpoint {
+                               remote-endpoint = <&adv7482_ain7>;
+                       };
+               };
+       };
+
+       /* CN2 */
+       /* Eagle: SW35 set 5, 6 and 8 to OFF */
+       hdmi-in-cn2 {
+               compatible = "hdmi-connector";
+               label = "HDMI IN CN2";
+               type = "a";
+
+               port {
+                       hdmi_in_con2: endpoint {
+                               remote-endpoint = <&adv7612_in>;
+                       };
+               };
+       };
+
+       /* CN3 */
+       /* Eagle: SW18 set to OFF */
+       hdmi-in-cn3 {
+               compatible = "hdmi-connector";
+               label = "HDMI IN CN3";
+               type = "a";
+
+               port {
+                       hdmi_in_con: endpoint {
+                               remote-endpoint = <&adv7482_hdmi>;
+                       };
+               };
+       };
+};
+
+/* Disconnect MAX9286 GMSL I2C. */
+&i2c3 {
+       status = "disabled";
+};
+
+/* Connect expansion board I2C. */
+&i2c0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       gpio@27 {
+               compatible = "onnn,pca9654";
+               reg = <0x27>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               vin0_adv7612_en {
+                       gpio-hog;
+                       gpios = <3 GPIO_ACTIVE_LOW>;
+                       output-high;
+                       line-name = "VIN0_ADV7612_ENn";
+               };
+       };
+
+       hdmi-decoder@4c {
+               compatible = "adi,adv7612";
+               reg = <0x4c>, <0x50>, <0x52>, <0x54>, <0x56>, <0x58>;
+               reg-names = "main", "afe", "rep", "edid", "hdmi", "cp";
+               interrupt-parent = <&gpio3>;
+               interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+               default-input = <0>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               adv7612_in: endpoint {
+                                       remote-endpoint = <&hdmi_in_con2>;
+                               };
+                       };
+
+                       port@2 {
+                               reg = <2>;
+
+                               adv7612_out: endpoint {
+                                       remote-endpoint = <&vin0_in>;
+                               };
+                       };
+               };
+       };
+
+       video-receiver@70 {
+               compatible = "adi,adv7482";
+               reg = <0x70 0x71 0x72 0x73 0x74 0x75
+                      0x60 0x61 0x62 0x63 0x64 0x65>;
+               reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater",
+                           "infoframe", "cbus", "cec", "sdp", "txa", "txb" ;
+               interrupt-parent = <&gpio3>;
+               interrupts = <03 IRQ_TYPE_LEVEL_LOW>, <04 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-names = "intrq1", "intrq2";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@7 {
+                               reg = <7>;
+
+                               adv7482_ain7: endpoint {
+                                       remote-endpoint = <&cvbs_con>;
+                               };
+                       };
+
+                       port@8 {
+                               reg = <8>;
+
+                               adv7482_hdmi: endpoint {
+                                       remote-endpoint = <&hdmi_in_con>;
+                               };
+                       };
+
+                       port@a {
+                               reg = <10>;
+
+                               adv7482_txa: endpoint {
+                                       clock-lanes = <0>;
+                                       data-lanes = <1 2 3 4>;
+                                       remote-endpoint = <&csi40_in>;
+                               };
+                       };
+               };
+       };
+
+};
+
+&csi40 {
+       status = "okay";
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+
+                       csi40_in: endpoint {
+                               clock-lanes = <0>;
+                               data-lanes = <1 2 3 4>;
+                               remote-endpoint = <&adv7482_txa>;
+                       };
+               };
+       };
+};
+
+&pfc {
+       vin0_pins_parallel: vin0 {
+               groups = "vin0_data12", "vin0_sync", "vin0_clk", "vin0_clkenb";
+               function = "vin0";
+       };
+};
+
+&vin0 {
+       status = "okay";
+
+       pinctrl-0 = <&vin0_pins_parallel>;
+       pinctrl-names = "default";
+
+       ports {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               port@0 {
+                       reg = <0>;
+
+                       vin0_in: endpoint {
+                               pclk-sample = <0>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               remote-endpoint = <&adv7612_out>;
+                       };
+               };
+       };
+};
+
+&vin1 {
+       status = "okay";
+};
+
+&vin2 {
+       status = "okay";
+};
+
+&vin3 {
+       status = "okay";
+};
index abfda5c6ca16922ed74c3286c8a94244407d5113..bc65a7b4d999740c3be78976d840a01880a77b85 100644 (file)
@@ -14,9 +14,9 @@
        compatible = "renesas,s4sk", "renesas,r8a779f4", "renesas,r8a779f0";
 
        aliases {
-               serial0 = &hscif0;
-               serial1 = &hscif1;
-               eth0    = &rswitch;
+               serial0 = &hscif0;
+               serial1 = &hscif1;
+               ethernet0 = &rswitch;
        };
 
        chosen {
index bc8616a56c039b20b0635e7d844e89735099cded..cfbe8c8680cd894734b8fc6357550740ae9fed5e 100644 (file)
 
        aliases {
                serial0 = &hscif0;
+               serial1 = &hscif2;
                ethernet0 = &avb0;
        };
 
        chosen {
-               bootargs = "ignore_loglevel";
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
                stdout-path = "serial0:921600n8";
        };
 
        status = "okay";
 };
 
+&hscif2 {
+       pinctrl-0 = <&hscif2_pins>;
+       pinctrl-names = "default";
+
+       uart-has-rtscts;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-0 = <&i2c0_pins>;
        pinctrl-names = "default";
 };
 
 &pfc {
-       pinctrl-0 = <&scif_clk_pins>;
+       pinctrl-0 = <&scif_clk_pins>, <&scif_clk2_pins>;
        pinctrl-names = "default";
 
        avb0_pins: avb0 {
                function = "hscif0";
        };
 
+       hscif2_pins: hscif2 {
+               groups = "hscif2_data", "hscif2_ctrl";
+               function = "hscif2";
+       };
+
        i2c0_pins: i2c0 {
                groups = "i2c0";
                function = "i2c0";
                groups = "scif_clk";
                function = "scif_clk";
        };
+
+       scif_clk2_pins: scif-clk2 {
+               groups = "scif_clk2";
+               function = "scif_clk2";
+       };
 };
 
 &rpc {
 &scif_clk {
        clock-frequency = <24000000>;
 };
+
+&scif_clk2 {
+       clock-frequency = <24000000>;
+};
index 11885729181bc9030484ad354ccf5f90302075ae..6d791024cabe1b94f01ad0514214a17ec613c075 100644 (file)
                method = "smc";
        };
 
-       /* External SCIF clock - to be overridden by boards that provide it */
+       /* External SCIF clocks - to be overridden by boards that provide them */
        scif_clk: scif-clk {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <0>;
        };
 
+       scif_clk2: scif-clk2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
        soc: soc {
                compatible = "simple-bus";
                interrupt-parent = <&gic>;
                        resets = <&cpg 917>;
                };
 
+               cmt0: timer@e60f0000 {
+                       compatible = "renesas,r8a779h0-cmt0",
+                                    "renesas,rcar-gen4-cmt0";
+                       reg = <0 0xe60f0000 0 0x1004>;
+                       interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 910>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 910>;
+                       status = "disabled";
+               };
+
+               cmt1: timer@e6130000 {
+                       compatible = "renesas,r8a779h0-cmt1",
+                                    "renesas,rcar-gen4-cmt1";
+                       reg = <0 0xe6130000 0 0x1004>;
+                       interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 911>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 911>;
+                       status = "disabled";
+               };
+
+               cmt2: timer@e6140000 {
+                       compatible = "renesas,r8a779h0-cmt1",
+                                    "renesas,rcar-gen4-cmt1";
+                       reg = <0 0xe6140000 0 0x1004>;
+                       interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 912>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 912>;
+                       status = "disabled";
+               };
+
+               cmt3: timer@e6148000 {
+                       compatible = "renesas,r8a779h0-cmt1",
+                                    "renesas,rcar-gen4-cmt1";
+                       reg = <0 0xe6148000 0 0x1004>;
+                       interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 913>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 913>;
+                       status = "disabled";
+               };
+
                cpg: clock-controller@e6150000 {
                        compatible = "renesas,r8a779h0-cpg-mssr";
                        reg = <0 0xe6150000 0 0x4000>;
                        #power-domain-cells = <1>;
                };
 
+               tsc: thermal@e6198000 {
+                       compatible = "renesas,r8a779h0-thermal";
+                       reg = <0 0xe6198000 0 0x200>,
+                             <0 0xe61a0000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 919>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 919>;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               intc_ex: interrupt-controller@e61c0000 {
+                       compatible = "renesas,intc-ex-r8a779h0", "renesas,irqc";
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       reg = <0 0xe61c0000 0 0x200>;
+                       interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 611>;
+               };
+
+               tmu0: timer@e61e0000 {
+                       compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+                       reg = <0 0xe61e0000 0 0x30>;
+                       interrupts = <GIC_SPI 289 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 290 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 291 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2";
+                       clocks = <&cpg CPG_MOD 713>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 713>;
+                       status = "disabled";
+               };
+
+               tmu1: timer@e6fc0000 {
+                       compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+                       reg = <0 0xe6fc0000 0 0x30>;
+                       interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 714>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 714>;
+                       status = "disabled";
+               };
+
+               tmu2: timer@e6fd0000 {
+                       compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+                       reg = <0 0xe6fd0000 0 0x30>;
+                       interrupts = <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 715>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 715>;
+                       status = "disabled";
+               };
+
+               tmu3: timer@e6fe0000 {
+                       compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+                       reg = <0 0xe6fe0000 0 0x30>;
+                       interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 301 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 716>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 716>;
+                       status = "disabled";
+               };
+
+               tmu4: timer@ffc00000 {
+                       compatible = "renesas,tmu-r8a779h0", "renesas,tmu";
+                       reg = <0 0xffc00000 0 0x30>;
+                       interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "tuni0", "tuni1", "tuni2", "ticpi2";
+                       clocks = <&cpg CPG_MOD 717>;
+                       clock-names = "fck";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 717>;
+                       status = "disabled";
+               };
+
                i2c0: i2c@e6500000 {
                        compatible = "renesas,i2c-r8a779h0",
                                     "renesas,rcar-gen4-i2c";
                        status = "disabled";
                };
 
+               hscif1: serial@e6550000 {
+                       compatible = "renesas,hscif-r8a779h0",
+                                    "renesas,rcar-gen4-hscif", "renesas,hscif";
+                       reg = <0 0xe6550000 0 0x60>;
+                       interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 515>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 515>;
+                       dmas = <&dmac1 0x33>, <&dmac1 0x32>,
+                              <&dmac2 0x33>, <&dmac2 0x32>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               hscif2: serial@e6560000 {
+                       compatible = "renesas,hscif-r8a779h0",
+                                    "renesas,rcar-gen4-hscif", "renesas,hscif";
+                       reg = <0 0xe6560000 0 0x60>;
+                       interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 516>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk2>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 516>;
+                       dmas = <&dmac1 0x35>, <&dmac1 0x34>,
+                              <&dmac2 0x35>, <&dmac2 0x34>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a779h0",
+                                    "renesas,rcar-gen4-hscif", "renesas,hscif";
+                       reg = <0 0xe66a0000 0 0x60>;
+                       interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 517>;
+                       dmas = <&dmac1 0x37>, <&dmac1 0x36>,
+                              <&dmac2 0x37>, <&dmac2 0x36>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
                avb0: ethernet@e6800000 {
                        compatible = "renesas,etheravb-r8a779h0",
                                     "renesas,etheravb-rcar-gen4";
                        phy-mode = "rgmii";
                        rx-internal-delay-ps = <0>;
                        tx-internal-delay-ps = <0>;
+                       iommus = <&ipmmu_hc 0>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                        status = "disabled";
                };
 
+               scif0: serial@e6e60000 {
+                       compatible = "renesas,scif-r8a779h0",
+                                    "renesas,rcar-gen4-scif", "renesas,scif";
+                       reg = <0 0xe6e60000 0 64>;
+                       interrupts = <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 702>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 702>;
+                       dmas = <&dmac1 0x51>, <&dmac1 0x50>,
+                              <&dmac2 0x51>, <&dmac2 0x50>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               scif1: serial@e6e68000 {
+                       compatible = "renesas,scif-r8a779h0",
+                                    "renesas,rcar-gen4-scif", "renesas,scif";
+                       reg = <0 0xe6e68000 0 64>;
+                       interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 703>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 703>;
+                       dmas = <&dmac1 0x53>, <&dmac1 0x52>,
+                              <&dmac2 0x53>, <&dmac2 0x52>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               scif3: serial@e6c50000 {
+                       compatible = "renesas,scif-r8a779h0",
+                                    "renesas,rcar-gen4-scif", "renesas,scif";
+                       reg = <0 0xe6c50000 0 64>;
+                       interrupts = <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 704>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 704>;
+                       dmas = <&dmac1 0x57>, <&dmac1 0x56>,
+                              <&dmac2 0x57>, <&dmac2 0x56>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               scif4: serial@e6c40000 {
+                       compatible = "renesas,scif-r8a779h0",
+                                    "renesas,rcar-gen4-scif", "renesas,scif";
+                       reg = <0 0xe6c40000 0 64>;
+                       interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 705>,
+                                <&cpg CPG_CORE R8A779H0_CLK_SASYNCPERD1>,
+                                <&scif_clk2>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 705>;
+                       dmas = <&dmac1 0x59>, <&dmac1 0x58>,
+                              <&dmac2 0x59>, <&dmac2 0x58>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       status = "disabled";
+               };
+
+               msiof0: spi@e6e90000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6e90000 0 0x0064>;
+                       interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 618>;
+                       dmas = <&dmac1 0x41>, <&dmac1 0x40>,
+                              <&dmac2 0x41>, <&dmac2 0x40>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 618>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof1: spi@e6ea0000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6ea0000 0 0x0064>;
+                       interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 619>;
+                       dmas = <&dmac1 0x43>, <&dmac1 0x42>,
+                              <&dmac2 0x43>, <&dmac2 0x42>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 619>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof2: spi@e6c00000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6c00000 0 0x0064>;
+                       interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 620>;
+                       dmas = <&dmac1 0x45>, <&dmac1 0x44>,
+                              <&dmac2 0x45>, <&dmac2 0x44>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 620>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof3: spi@e6c10000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6c10000 0 0x0064>;
+                       interrupts = <GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 621>;
+                       dmas = <&dmac1 0x47>, <&dmac1 0x46>,
+                              <&dmac2 0x47>, <&dmac2 0x46>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 621>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof4: spi@e6c20000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6c20000 0 0x0064>;
+                       interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 622>;
+                       dmas = <&dmac1 0x49>, <&dmac1 0x48>,
+                              <&dmac2 0x49>, <&dmac2 0x48>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 622>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               msiof5: spi@e6c28000 {
+                       compatible = "renesas,msiof-r8a779h0",
+                                    "renesas,rcar-gen4-msiof";
+                       reg = <0 0xe6c28000 0 0x0064>;
+                       interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 623>;
+                       dmas = <&dmac1 0x4b>, <&dmac1 0x4a>,
+                              <&dmac2 0x4b>, <&dmac2 0x4a>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       resets = <&cpg 623>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                dmac1: dma-controller@e7350000 {
                        compatible = "renesas,dmac-r8a779h0",
                                     "renesas,rcar-gen4-dmac";
                        resets = <&cpg 709>;
                        #dma-cells = <1>;
                        dma-channels = <16>;
+                       iommus = <&ipmmu_ds0 0>, <&ipmmu_ds0 1>,
+                                <&ipmmu_ds0 2>, <&ipmmu_ds0 3>,
+                                <&ipmmu_ds0 4>, <&ipmmu_ds0 5>,
+                                <&ipmmu_ds0 6>, <&ipmmu_ds0 7>,
+                                <&ipmmu_ds0 8>, <&ipmmu_ds0 9>,
+                                <&ipmmu_ds0 10>, <&ipmmu_ds0 11>,
+                                <&ipmmu_ds0 12>, <&ipmmu_ds0 13>,
+                                <&ipmmu_ds0 14>, <&ipmmu_ds0 15>;
                };
 
                dmac2: dma-controller@e7351000 {
                        resets = <&cpg 710>;
                        #dma-cells = <1>;
                        dma-channels = <8>;
+                       iommus = <&ipmmu_ds0 16>, <&ipmmu_ds0 17>,
+                                <&ipmmu_ds0 18>, <&ipmmu_ds0 19>,
+                                <&ipmmu_ds0 20>, <&ipmmu_ds0 21>,
+                                <&ipmmu_ds0 22>, <&ipmmu_ds0 23>;
                };
 
                mmc0: mmc@ee140000 {
                        power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
                        resets = <&cpg 706>;
                        max-frequency = <200000000>;
+                       iommus = <&ipmmu_ds0 32>;
                        status = "disabled";
                };
 
                        status = "disabled";
                };
 
+               ipmmu_rt0: iommu@ee480000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xee480000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_rt1: iommu@ee4c0000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xee4c0000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ds0: iommu@eed00000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeed00000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_hc: iommu@eed40000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeed40000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_ir: iommu@eed80000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeed80000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vc: iommu@eedc0000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeedc0000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_3dg: iommu@eee00000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeee00000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi0: iommu@eee80000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeee80000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vi1: iommu@eeec0000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeeec0000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_vip0: iommu@eef00000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeef00000 0 0x20000>;
+                       renesas,ipmmu-main = <&ipmmu_mm>;
+                       power-domains = <&sysc R8A779H0_PD_C4>;
+                       #iommu-cells = <1>;
+               };
+
+               ipmmu_mm: iommu@eefc0000 {
+                       compatible = "renesas,ipmmu-r8a779h0",
+                                    "renesas,rcar-gen4-ipmmu-vmsa";
+                       reg = <0 0xeefc0000 0 0x20000>;
+                       interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&sysc R8A779H0_PD_ALWAYS_ON>;
+                       #iommu-cells = <1>;
+               };
+
                gic: interrupt-controller@f1000000 {
                        compatible = "arm,gic-v3";
                        #interrupt-cells = <3>;
                };
        };
 
+       thermal-zones {
+               sensor_thermal_cr52: sensor1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 0>;
+
+                       trips {
+                               sensor1_crit: sensor1-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               sensor_thermal_ca76: sensor2-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+                       thermal-sensors = <&tsc 1>;
+
+                       trips {
+                               sensor2_crit: sensor2-crit {
+                                       temperature = <120000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+       };
+
        timer {
                compatible = "arm,armv8-timer";
                interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
index 8721f4c9fa0fb486e1bbd70bd2645542b0c853de..d2365def10591a5982c0a1da9f4ccf8031a9db14 100644 (file)
                        gpio-ranges = <&pinctrl 0 0 152>;
                        #interrupt-cells = <2>;
                        interrupt-controller;
+                       interrupt-parent = <&irqc>;
                        clocks = <&cpg CPG_MOD R9A07G043_GPIO_HCLK>;
                        power-domains = <&cpg>;
                        resets = <&cpg R9A07G043_GPIO_RSTN>,
index 964b0a475eeeb6080f385750f795117db4fa31e3..165bfcfef3bcc69c931a4e85f4e9c4d222661b31 100644 (file)
        };
 };
 
-&pinctrl {
-       interrupt-parent = <&irqc>;
-};
-
 &soc {
        interrupt-parent = <&gic>;
 
index de590996e10af2162cc2b71117814ac9dcd42dba..433860987f738cc9f5080d6d1b77175bde96db55 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (C) 2022 Renesas Electronics Corp.
  */
 
+#include <dt-bindings/gpio/gpio.h>
 #include "rzg2ul-smarc-pinfunction.dtsi"
 #include "rz-smarc-common.dtsi"
 
 &i2c0 {
        clock-frequency = <400000>;
 
+       da9062: pmic@58 {
+               compatible = "dlg,da9062";
+               reg = <0x58>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio {
+                       compatible = "dlg,da9062-gpio";
+               };
+
+               onkey {
+                       compatible = "dlg,da9062-onkey";
+               };
+
+               pmic-good-hog {
+                       gpio-hog;
+                       gpios = <4 GPIO_ACTIVE_HIGH>;
+                       output-high;
+                       line-name = "PMIC_PGOOD";
+               };
+
+               rtc {
+                       compatible = "dlg,da9062-rtc";
+               };
+
+               sd0-pwr-sel-hog {
+                       gpio-hog;
+                       gpios = <1 GPIO_ACTIVE_HIGH>;
+                       input;
+                       line-name = "SD0_PWR_SEL";
+               };
+
+               sd1-pwr-sel-hog {
+                       gpio-hog;
+                       gpios = <2 GPIO_ACTIVE_HIGH>;
+                       input;
+                       line-name = "SD1_PWR_SEL";
+               };
+
+               sw-et0-en-hog {
+                       gpio-hog;
+                       gpios = <3 GPIO_ACTIVE_HIGH>;
+                       input;
+                       line-name = "SW_ET0_EN#";
+               };
+
+               thermal {
+                       compatible = "dlg,da9062-thermal";
+                       status = "disabled";
+               };
+
+               watchdog {
+                       compatible = "dlg,da9062-watchdog";
+                       status = "disabled";
+               };
+       };
+
        versa3: clock-generator@68 {
                compatible = "renesas,5p35023";
                reg = <0x68>;
index acac4666ae59e38c1303806a9d188fb9dcd9b9a9..8a3d302f1535783ab221f29731cdb0a9dfd74b03 100644 (file)
@@ -25,7 +25,7 @@
  *     SW_OFF - SD2 is connected to SoC
  *     SW_ON  - SCIF1, SSI0, IRQ0, IRQ1 connected to SoC
  */
-#define SW_CONFIG2     SW_ON
+#define SW_CONFIG2     SW_OFF
 #define SW_CONFIG3     SW_ON
 
 / {
@@ -36,8 +36,8 @@
 #if SW_CONFIG3 == SW_OFF
                mmc2 = &sdhi2;
 #else
-               eth0 = &eth0;
-               eth1 = &eth1;
+               ethernet0 = &eth0;
+               ethernet1 = &eth1;
 #endif
        };
 
index f906a868b71acad873485bcafe25ccf3649f5798..f42fa62b4064a781b6abe3a238bd6af13a6391a7 100644 (file)
@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351m.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351v.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-gameforce-chi.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2-v11.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go3.dtb
@@ -90,6 +91,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-b.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-radxa-cm3-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-roc-pc.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rock-3c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-blade.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-cm4.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-soquartz-model-a.dtb
@@ -100,6 +102,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r66s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-fastrhino-r68s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-lubancat-2.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-mecsbc.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-nanopi-r5s.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-odroid-m1.dtb
@@ -107,6 +110,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-qnap-ts433.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-radxa-e25.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-roc-pc.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-rock-3a.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-wolfvision-pf5-io-expander.dtbo
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtbo
@@ -114,6 +120,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6b-io.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-v10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-ok3588-c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-orangepi-5-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-quartzpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b.dtb
index cfc0a87b5195930d0527ba49a8b2995042538184..962ea893999bd9dcdce4ce8463062df76fdc495d 100644 (file)
                #dma-cells = <1>;
        };
 
+       /*
+        * - can be clock producer or consumer
+        * - up to 8 capture channels and 2 playback channels
+        * - connected internally to audio codec
+        */
+       i2s_8ch_2: i2s@ff320000 {
+               compatible = "rockchip,rk3308-i2s-tdm";
+               reg = <0x0 0xff320000 0x0 0x1000>;
+               interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+               clock-names = "mclk_tx", "mclk_rx", "hclk";
+               clocks = <&cru SCLK_I2S2_8CH_TX>,
+                        <&cru SCLK_I2S2_8CH_RX>,
+                        <&cru HCLK_I2S2_8CH>;
+               dmas = <&dmac1 5>, <&dmac1 4>;
+               dma-names = "rx", "tx";
+               resets = <&cru SRST_I2S2_8CH_TX_M>, <&cru SRST_I2S2_8CH_RX_M>;
+               reset-names = "tx-m", "rx-m";
+               rockchip,grf = <&grf>;
+               status = "disabled";
+       };
+
+       /*
+        * - can be clock consumer only
+        * - up to 4 capture channels, no playback
+        * - connected internally to audio codec
+        */
+       i2s_8ch_3: i2s@ff330000 {
+               compatible = "rockchip,rk3308-i2s-tdm";
+               reg = <0x0 0xff330000 0x0 0x1000>;
+               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+               clock-names = "mclk_tx", "mclk_rx", "hclk";
+               clocks = <&cru SCLK_I2S3_8CH_TX>,
+                        <&cru SCLK_I2S3_8CH_RX>,
+                        <&cru HCLK_I2S3_8CH>;
+               dmas = <&dmac1 7>;
+               dma-names = "rx";
+               resets = <&cru SRST_I2S3_8CH_TX_M>, <&cru SRST_I2S3_8CH_RX_M>;
+               reset-names = "tx-m", "rx-m";
+               rockchip,grf = <&grf>;
+               status = "disabled";
+       };
+
        i2s_2ch_0: i2s@ff350000 {
                compatible = "rockchip,rk3308-i2s", "rockchip,rk3066-i2s";
                reg = <0x0 0xff350000 0x0 0x1000>;
                assigned-clock-rates = <32768>;
        };
 
+       codec: codec@ff560000 {
+               compatible = "rockchip,rk3308-codec";
+               reg = <0x0 0xff560000 0x0 0x10000>;
+               rockchip,grf = <&grf>;
+               clock-names = "mclk_tx", "mclk_rx", "hclk";
+               clocks = <&cru SCLK_I2S2_8CH_TX_OUT>,
+                        <&cru SCLK_I2S2_8CH_RX_OUT>,
+                        <&cru PCLK_ACODEC>;
+               reset-names = "codec-reset";
+               resets = <&cru SRST_ACODEC_P>;
+               #sound-dai-cells = <0>;
+               status = "disabled";
+       };
+
        gic: interrupt-controller@ff580000 {
                compatible = "arm,gic-400";
                reg = <0x0 0xff581000 0x0 0x1000>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts b/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
new file mode 100644 (file)
index 0000000..579261b
--- /dev/null
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Chris Morgan <macromorgan@hotmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3326.dtsi"
+
+/ {
+       model = "GameForce Chi";
+       compatible = "gameforce,chi", "rockchip,rk3326";
+       chassis-type = "handset";
+
+       aliases {
+               mmc0 = &sdmmc;
+               mmc1 = &sdio;
+       };
+
+       chosen {
+               stdout-path = "serial2:115200n8";
+       };
+
+       adc_joystick: adc-joystick {
+               compatible = "adc-joystick";
+               io-channels = <&saradc 0>,
+                             <&saradc 1>;
+               poll-interval = <100>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               axis@0 {
+                       reg = <0>;
+                       abs-flat = <10>;
+                       abs-fuzz = <10>;
+                       abs-range = <850 175>;
+                       linux,code = <ABS_Y>;
+               };
+
+               axis@1 {
+                       reg = <1>;
+                       abs-flat = <10>;
+                       abs-fuzz = <10>;
+                       abs-range = <800 190>;
+                       linux,code = <ABS_X>;
+               };
+       };
+
+       adc_keys: adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 2>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+               poll-interval = <60>;
+
+               button-1 {
+                       label = "HAPPY1";
+                       linux,code = <BTN_TRIGGER_HAPPY1>;
+                       press-threshold-microvolt = <15000>;
+               };
+
+               button-2 {
+                       label = "HAPPY2";
+                       linux,code = <BTN_TRIGGER_HAPPY2>;
+                       press-threshold-microvolt = <300000>;
+               };
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               power-supply = <&vcc_bl>;
+               pwms = <&pwm1 0 25000 0>;
+       };
+
+       battery: battery {
+               compatible = "simple-battery";
+               charge-full-design-microamp-hours = <3000000>;
+               charge-term-current-microamp = <300000>;
+               constant-charge-current-max-microamp = <1500000>;
+               constant-charge-voltage-max-microvolt = <4200000>;
+               factory-internal-resistance-micro-ohms = <180000>;
+               ocv-capacity-celsius = <20>;
+               ocv-capacity-table-0 =  <4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>,
+                                       <3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>,
+                                       <3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>,
+                                       <3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>,
+                                       <3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>,
+                                       <3400000 0>;
+               voltage-max-design-microvolt = <4250000>;
+               voltage-min-design-microvolt = <3400000>;
+       };
+
+       gpio_leds: gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_pins>;
+
+               red_led: led-0 {
+                       color = <LED_COLOR_ID_RED>;
+                       gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+               };
+
+               green_led: led-1 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+               };
+
+               blue_led: led-2 {
+                       color = <LED_COLOR_ID_BLUE>;
+                       gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+               };
+
+               white_led: led-3 {
+                       color = <LED_COLOR_ID_WHITE>;
+                       function = LED_FUNCTION_STATUS;
+                       gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+               };
+
+               chg_led: led-4 {
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_CHARGING;
+                       gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+               };
+
+       };
+
+       gpio_keys: gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&btn_pins_ctrl>;
+               pinctrl-names = "default";
+
+               button-a {
+                       gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>;
+                       label = "EAST";
+                       linux,code = <BTN_EAST>;
+               };
+
+               button-b {
+                       gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;
+                       label = "SOUTH";
+                       linux,code = <BTN_SOUTH>;
+               };
+
+               button-down {
+                       gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>;
+                       label = "DPAD-DOWN";
+                       linux,code = <BTN_DPAD_DOWN>;
+               };
+
+               button-home {
+                       gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>;
+                       label = "HOME";
+                       linux,code = <BTN_MODE>;
+               };
+
+               button-l1 {
+                       gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>;
+                       label = "TL";
+                       linux,code = <BTN_TL>;
+               };
+
+               button-l2 {
+                       gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;
+                       label = "TL2";
+                       linux,code = <BTN_TL2>;
+               };
+
+               button-left {
+                       gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>;
+                       label = "DPAD-LEFT";
+                       linux,code = <BTN_DPAD_LEFT>;
+               };
+
+               button-r1 {
+                       gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>;
+                       label = "TR";
+                       linux,code = <BTN_TR>;
+               };
+
+               button-r2 {
+                       gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
+                       label = "TR2";
+                       linux,code = <BTN_TR2>;
+               };
+
+               button-right {
+                       gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>;
+                       label = "DPAD-RIGHT";
+                       linux,code = <BTN_DPAD_RIGHT>;
+               };
+
+               button-select {
+                       gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;
+                       label = "SELECT";
+                       linux,code = <BTN_SELECT>;
+               };
+
+               button-start {
+                       gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+                       label = "START";
+                       linux,code = <BTN_START>;
+               };
+
+               button-up {
+                       gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+                       label = "DPAD-UP";
+                       linux,code = <BTN_DPAD_UP>;
+               };
+
+               button-x {
+                       gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+                       label = "NORTH";
+                       linux,code = <BTN_NORTH>;
+               };
+
+               button-y {
+                       gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+                       label = "WEST";
+                       linux,code = <BTN_WEST>;
+               };
+       };
+
+       multi-led {
+               compatible = "leds-group-multicolor";
+               color = <LED_COLOR_ID_RGB>;
+               function = LED_FUNCTION_KBD_BACKLIGHT;
+               leds = <&red_led>, <&green_led>, <&blue_led>;
+       };
+
+       spk_amp: audio-amplifier {
+               compatible = "simple-audio-amplifier";
+               enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-0 = <&spk_amp_enable_h>;
+               pinctrl-names = "default";
+               sound-name-prefix = "Speaker Amp";
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+               pinctrl-0 = <&hp_det>;
+               pinctrl-names = "default";
+               simple-audio-card,name = "rk817_ext";
+               simple-audio-card,aux-devs = <&spk_amp>;
+               simple-audio-card,format = "i2s";
+               simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
+               simple-audio-card,mclk-fs = <256>;
+               simple-audio-card,widgets =
+                       "Microphone", "Mic Jack",
+                       "Headphone", "Headphones",
+                       "Speaker", "Internal Speakers";
+               simple-audio-card,routing =
+                       "MICL", "Mic Jack",
+                       "Headphones", "HPOL",
+                       "Headphones", "HPOR",
+                       "Internal Speakers", "Speaker Amp OUTL",
+                       "Internal Speakers", "Speaker Amp OUTR",
+                       "Speaker Amp INL", "HPOL",
+                       "Speaker Amp INR", "HPOR";
+               simple-audio-card,pin-switches = "Internal Speakers";
+
+               simple-audio-card,codec {
+                       sound-dai = <&rk817>;
+               };
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s1_2ch>;
+               };
+       };
+
+       vibrator_left: pwm-vibrator-l {
+               compatible = "pwm-vibrator";
+               pwm-names = "enable";
+               pwms = <&pwm4 0 25000 0>;
+       };
+
+       vibrator_right: pwm-vibrator-r {
+               compatible = "pwm-vibrator";
+               pwm-names = "enable";
+               pwms = <&pwm5 0 25000 0>;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk817 1>;
+               clock-names = "ext_clock";
+               pinctrl-0 = <&wifi_enable_h>;
+               pinctrl-names = "default";
+               post-power-on-delay-ms = <200>;
+               reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+       };
+
+       vccsys: vccsys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v8_sys";
+               regulator-always-on;
+               regulator-min-microvolt = <3800000>;
+               regulator-max-microvolt = <3800000>;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+       status = "okay";
+};
+
+&dsi {
+       status = "okay";
+
+       internal_display: panel@0 {
+               reg = <0>;
+               compatible = "gameforce,chi-panel";
+               backlight = <&backlight>;
+               iovcc-supply = <&vcc_lcd>;
+               vcc-supply = <&vcc_lcd>;
+               reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>;
+
+               port {
+                       mipi_in_panel: endpoint {
+                               remote-endpoint = <&mipi_out_panel>;
+                       };
+               };
+       };
+
+       ports {
+               mipi_out: port@1 {
+                       reg = <1>;
+
+                       mipi_out_panel: endpoint {
+                               remote-endpoint = <&mipi_in_panel>;
+                       };
+               };
+       };
+};
+
+&dsi_dphy {
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_logic>;
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-falling-time-ns = <16>;
+       i2c-scl-rising-time-ns = <280>;
+       status = "okay";
+
+       rk817: pmic@20 {
+               compatible = "rockchip,rk817";
+               reg = <0x20>;
+               #clock-cells = <1>;
+               clock-names = "mclk";
+               clock-output-names = "rk808-clkout1", "xin32k";
+               clocks = <&cru SCLK_I2S1_OUT>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PC1 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>;
+               pinctrl-names = "default";
+               #sound-dai-cells = <0>;
+               system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vccsys>;
+               vcc2-supply = <&vccsys>;
+               vcc3-supply = <&vccsys>;
+               vcc4-supply = <&vccsys>;
+               vcc5-supply = <&vccsys>;
+               vcc6-supply = <&vccsys>;
+               vcc7-supply = <&vcc_3v0>;
+               vcc8-supply = <&vccsys>;
+               vcc9-supply = <&dcdc_boost>;
+
+               regulators {
+                       vdd_logic: DCDC_REG1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <1150000>;
+                               regulator-min-microvolt = <950000>;
+                               regulator-name = "vdd_logic";
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <950000>;
+                               };
+                       };
+
+                       vdd_arm: DCDC_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-min-microvolt = <950000>;
+                               regulator-name = "vdd_arm";
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <950000>;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vcc_ddr";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_3v0: DCDC_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-name = "vcc_3v0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc_1v8: LDO_REG2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_1v0: LDO_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-min-microvolt = <1000000>;
+                               regulator-name = "vdd_1v0";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1000000>;
+                               };
+                       };
+
+                       vcc_3v0_pmu: LDO_REG4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-name = "vcc_3v0_pmu";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-name = "vccio_sd";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_sd: LDO_REG6 {
+                               regulator-boot-on;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-name = "vcc_sd";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_bl: LDO_REG7 {
+                               regulator-max-microvolt = <3300000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-name = "vcc_bl";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_lcd: LDO_REG8 {
+                               regulator-max-microvolt = <2800000>;
+                               regulator-min-microvolt = <2800000>;
+                               regulator-name = "vcc_lcd";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <2800000>;
+                               };
+                       };
+
+                       vcc_wifi: LDO_REG9 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-name = "vcc_wifi";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       dcdc_boost: BOOST {
+                               regulator-max-microvolt = <5000000>;
+                               regulator-min-microvolt = <5000000>;
+                               regulator-name = "dcdc_boost";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       otg_switch: OTG_SWITCH {
+                               regulator-name = "otg_switch";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+
+               rk817_charger: charger {
+                       monitored-battery = <&battery>;
+                       rockchip,resistor-sense-micro-ohms = <10000>;
+                       rockchip,sleep-enter-current-microamp = <300000>;
+                       rockchip,sleep-filter-current-microamp = <100000>;
+               };
+       };
+};
+
+&i2s1_2ch {
+       status = "okay";
+};
+
+&io_domains {
+       vccio1-supply = <&vcc_3v0_pmu>;
+       vccio2-supply = <&vccio_sd>;
+       vccio3-supply = <&vcc_3v0>;
+       vccio4-supply = <&vcc_3v0>;
+       vccio5-supply = <&vcc_3v0>;
+       vccio6-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pinctrl {
+       bluetooth-pins {
+               bt_reset: bt-reset {
+                       rockchip,pins =
+                               <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               bt_wake_dev: bt-wake-dev {
+                       rockchip,pins =
+                               <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_wake_host: bt-wake-host {
+                       rockchip,pins =
+                               <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       headphone {
+               hp_det: hp-det {
+                       rockchip,pins =
+                               <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       gpio-btns {
+               btn_pins_ctrl: btn-pins-ctrl {
+                       rockchip,pins =
+                               <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
+                               <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       gpio-leds {
+               led_pins: led-pins {
+                       rockchip,pins =
+                               <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>,
+                               <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
+                               <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+                               <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>,
+                               <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int: pmic-int {
+                       rockchip,pins =
+                               <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               soc_slppin_gpio: soc_slppin_gpio {
+                       rockchip,pins =
+                               <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               soc_slppin_rst: soc_slppin_rst {
+                       rockchip,pins =
+                               <0 RK_PA4 2 &pcfg_pull_none>;
+               };
+
+               soc_slppin_slp: soc_slppin_slp {
+                       rockchip,pins =
+                               <0 RK_PA4 1 &pcfg_pull_none>;
+               };
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h: wifi-enable-h {
+                       rockchip,pins =
+                               <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       speaker {
+               spk_amp_enable_h: spk-amp-enable-h {
+                       rockchip,pins =
+                               <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       pmuio1-supply = <&vcc_1v8>;
+       pmuio2-supply = <&vcc_3v0_pmu>;
+       status = "okay";
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&pwm4 {
+       status = "okay";
+};
+
+&pwm5 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcc_1v8>;
+       status = "okay";
+};
+
+&sdio {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cap-sdio-irq;
+       disable-wp;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       no-mmc;
+       no-sd;
+       non-removable;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&sdmmc {
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       no-sdio;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc_sd>;
+       vqmmc-supply = <&vccio_sd>;
+       status = "okay";
+};
+
+&sfc {
+       #address-cells = <1>;
+       pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
+       pinctrl-names = "default";
+       #size-cells = <0>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <108000000>;
+               spi-rx-bus-width = <2>;
+               spi-tx-bus-width = <1>;
+       };
+};
+
+&tsadc {
+       status = "okay";
+};
+
+&u2phy {
+       status = "okay";
+
+       u2phy_otg: otg-port {
+               status = "okay";
+       };
+};
+
+&usb20_otg {
+       status = "okay";
+};
+
+/*
+ * The right ADC joystick exists connected to an unknown ADC
+ * controller which can be communicated with via uart0. This ADC device
+ * is an 8-pin SOIC with no markings located right next to the left ADC
+ * joystick ribbon cable. The pinout for this ADC controller appears to
+ * be pin 1 - VCC (2.8v), pin 2 - 1.8v (clk maybe?), pin 3 - GPIO 10,
+ * pin 4 - unknown, pin 5 - unknown, pin 6 - analog in, pin 7 - analog in,
+ * pin 8 - ground. There is currently a userspace UART driver for this
+ * device but it only works with the BSP joystick driver.
+ */
+&uart0 {
+       status = "okay";
+};
+
+/*
+ * Bluetooth was not working on BSP and is not currently working on
+ * mainline due to missing firmware. Bluetooth requires removal of DMA
+ * or else it will not probe.
+ */
+&uart1 {
+       /delete-property/ dma-names;
+       /delete-property/ dmas;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth: bluetooth {
+               compatible = "realtek,rtl8723ds-bt";
+               device-wake-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
+               enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+               host-wake-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+               pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>;
+               pinctrl-names = "default";
+       };
+};
+
+&uart2 {
+       pinctrl-0 = <&uart2m1_xfer>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
index b6f045069ee2f059b453c503d488112de6d709a8..07dcc949b8997e8bfd601e5e21230a5e22e05835 100644 (file)
                        cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
-                       next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l2_cache>;
                };
 
                cpu1: cpu@1 {
                        cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
-                       next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l2_cache>;
                };
 
                cpu2: cpu@2 {
                        cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
-                       next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l2_cache>;
                };
 
                cpu3: cpu@3 {
                        cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
-                       next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <256>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l2_cache>;
                };
 
                idle-states {
                        };
                };
 
-               l2: l2-cache0 {
+               l2_cache: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
                        cache-unified;
+                       cache-size = <0x40000>;
+                       cache-line-size = <64>;
+                       cache-sets = <256>;
                };
        };
 
index b48b98c13705c385ccceb1c66066eb24be854636..e5c0dbf794ae7e112dca6bc8d9cd09baca14d910 100644 (file)
@@ -17,7 +17,7 @@
                stdout-path = "serial2:115200n8";
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x0 0x0 0x40000000>;
        };
index dcee2e28916f710faa519de1adda98c070fc222d..23ae2d9de38226f922694409c66a1a26ec87a234 100644 (file)
@@ -21,7 +21,7 @@
                stdout-path = "serial2:115200n8";
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x0 0x0 0x80000000>;
        };
index b16b7ca02379a82f5daceb56ea516bc69744e539..7f14206d53c396b4c90ea3d7bc6d673113c61fb5 100644 (file)
@@ -21,7 +21,7 @@
                stdout-path = "serial2:115200n8";
        };
 
-       memory {
+       memory@0 {
                device_type = "memory";
                reg = <0x0 0x0 0x0 0x40000000>;
        };
index 62af0cb94839bba5f6e0c6e368f65fa0f35d10de..734f87db4d115d9e45c72aca7a4f7eb99317b1c1 100644 (file)
        };
 
        arm-pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
index 61f3fec5a8b1d60a6707504d2cf971a392bf19e9..e5709c7ee06aae00de16032d5d2fb01ffd7ffc47 100644 (file)
@@ -16,7 +16,7 @@
 #include "rk3399-opp.dtsi"
 
 / {
-       model = "Pine64 PinePhonePro";
+       model = "Pine64 PinePhone Pro";
        compatible = "pine64,pinephone-pro", "rockchip,rk3399";
        chassis-type = "handset";
 
index 7baf9d1b22fd5fd9e88cfd37ade59377d3ce2829..972aea843afd698e21681ea1da9f30d603d7c68a 100644 (file)
 };
 
 &emmc_phy {
+       rockchip,enable-strobe-pulldown;
        status = "okay";
 };
 
 &sdhci {
        max-frequency = <150000000>;
        bus-width = <8>;
-       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
        non-removable;
        status = "okay";
 };
index 281a12180703433462fa9f4fb7e0ed1f2dfaeeef..b9d6284bb804f7fcb0d6408397a9cf632978199b 100644 (file)
 };
 
 &emmc_phy {
+       rockchip,enable-strobe-pulldown;
        status = "okay";
 };
 
 &sdhci {
        max-frequency = <150000000>;
        bus-width = <8>;
-       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
        non-removable;
        status = "okay";
 };
index 8aa93c646becfa501a5ae0022147012ba25e258b..a73cf30801ec7f33fc5ef42cd5288c99400f95df 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-anbernic-rg353x.dtsi"
 
 / {
-       model = "RG353P";
+       model = "Anbernic RG353P";
        compatible = "anbernic,rg353p", "rockchip,rk3566";
 
        aliases {
index b211973e36c2176b1003fe12c74e376af90b70a8..ca5284e4807d80b2327045e7dc8e900869f3c175 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-anbernic-rg353x.dtsi"
 
 / {
-       model = "RG353PS";
+       model = "Anbernic RG353PS";
        compatible = "anbernic,rg353ps", "rockchip,rk3566";
 
        aliases {
index f49ce29ba5977d6c59ec58067d0de49f26227fe3..e9954a33e8cd31f20890ac39e0d03428e87a86af 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-anbernic-rg353x.dtsi"
 
 / {
-       model = "RG353V";
+       model = "Anbernic RG353V";
        compatible = "anbernic,rg353v", "rockchip,rk3566";
 
        aliases {
index a7dc462fe21f0d99d9d895619175c7618dba1a23..90da43855d1cbc54dcbbba5a5766c2c70f671590 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-anbernic-rg353x.dtsi"
 
 / {
-       model = "RG353VS";
+       model = "Anbernic RG353VS";
        compatible = "anbernic,rg353vs", "rockchip,rk3566";
 
        aliases {
index 94e6dd61a2dbb4f1bca3efb7106c1d500ac3cb06..74cf313e06355570129b58ff4bf97864c3e9c6e1 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-anbernic-rgxx3.dtsi"
 
 / {
-       model = "RG503";
+       model = "Anbernic RG503";
        compatible = "anbernic,rg503", "rockchip,rk3566";
 
        aliases {
index 18b8c2e7befa75712c0e2b1af9b35113ffec4d84..233eade30f211017e4db301cf67f0c66e8bef38f 100644 (file)
@@ -10,6 +10,8 @@
 #include "rk3566.dtsi"
 
 / {
+       chassis-type = "handset";
+
        chosen: chosen {
                stdout-path = "serial2:1500000n8";
        };
        cap-sdio-irq;
        keep-power-in-suspend;
        mmc-pwrseq = <&sdio_pwrseq>;
+       no-mmc;
+       no-sd;
        non-removable;
        pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
        pinctrl-names = "default";
+       sd-uhs-sdr50;
        vmmc-supply = <&vcc_wifi>;
        vqmmc-supply = <&vcca1v8_pmu>;
        status = "okay";
index 1f567a14ac84e00b321a37459fba78b3fc2a8863..952b1b285f3b490db4fe4972ecffe4375f7ec360 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-powkiddy-rk2023.dtsi"
 
 / {
-       model = "RGB30";
+       model = "Powkiddy RGB30";
        compatible = "powkiddy,rgb30", "rockchip,rk3566";
 };
 
index bc9933d9e2626cce2f511c051ab8295ad0c65372..72890f747ee393281be0b8d3a4611c4259073a4a 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566-powkiddy-rk2023.dtsi"
 
 / {
-       model = "RK2023";
+       model = "Powkiddy RK2023";
        compatible = "powkiddy,rk2023", "rockchip,rk3566";
 };
 
index 3ab751a01cb209023cfacff7d870236e3c828007..bd332714a023985d96fd320dfe60a1f0d8ccf435 100644 (file)
@@ -10,6 +10,8 @@
 #include "rk3566.dtsi"
 
 / {
+       chassis-type = "handset";
+
        aliases {
                mmc1 = &sdmmc0;
                mmc2 = &sdmmc1;
index 4786b19fd01786add59224103919197d636034e0..5a648db41f355e873dfdbc5be660622292a017fe 100644 (file)
@@ -11,6 +11,7 @@
 
 / {
        model = "Powkiddy x55";
+       chassis-type = "handset";
        compatible = "powkiddy,x55", "rockchip,rk3566";
 
        aliases {
index 59843a7a199c24a2ceabcd9a15c9a990525cb31c..0b191d8462ad85757a48794c884f36b569ff202f 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566.dtsi"
 
 / {
-       model = "Pine64 RK3566 Quartz64-A Board";
+       model = "Pine64 Quartz64 Model A";
        compatible = "pine64,quartz64-a", "rockchip,rk3566";
 
        aliases {
index 2d92713be2a09f97ca603cbb64bdc49fd4fc00db..26322a358d919a5c732a3d86cd79915aa38e9cb3 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566.dtsi"
 
 / {
-       model = "Pine64 RK3566 Quartz64-B Board";
+       model = "Pine64 Quartz64 Model B";
        compatible = "pine64,quartz64-b", "rockchip,rk3566";
 
        aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts
new file mode 100644 (file)
index 0000000..b242409
--- /dev/null
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+       model = "Radxa ROCK 3C";
+       compatible = "radxa,rock-3c", "rockchip,rk3566";
+
+       aliases {
+               ethernet0 = &gmac1;
+               mmc0 = &sdhci;
+               mmc1 = &sdmmc0;
+               mmc2 = &sdmmc1;
+       };
+
+       chosen: chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       gmac1_clkin: external-gmac1-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "gmac1_clkin";
+               #clock-cells = <0>;
+       };
+
+       hdmi-con {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led-0 {
+                       gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+                       function = LED_FUNCTION_HEARTBEAT;
+                       color = <LED_COLOR_ID_BLUE>;
+                       linux,default-trigger = "heartbeat";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&user_led2>;
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk809 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_reg_on_h>;
+               post-power-on-delay-ms = <100>;
+               power-off-delay-us = <5000000>;
+               reset-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
+       };
+
+       vcc5v_dcin: vcc5v-dcin-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v_dcin";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       vcc3v3_pcie: vcc3v3-pcie-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie_pwr_en>;
+               regulator-name = "vcc3v3_pcie";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       vcc3v3_sys: vcc3v3-sys-regulator {
+               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>;
+       };
+
+       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 = <&vcc5v_dcin>;
+       };
+
+       vcc5v0_usb30_host: vcc5v0-usb30-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_usb30_host_en>;
+               regulator-name = "vcc5v0_usb30_host";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_usb_otg_en>;
+               regulator-name = "vcc5v0_usb_otg";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc_cam: vcc-cam-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc_cam_en>;
+               regulator-name = "vcc_cam";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vcc_mipi: vcc-mipi-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc_mipi_en>;
+               regulator-name = "vcc_mipi";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&combphy1 {
+       status = "okay";
+};
+
+&combphy2 {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+       assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+       assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&gmac1_clkin>;
+       clock_in_out = "input";
+       phy-handle = <&rgmii_phy1>;
+       phy-mode = "rgmii-id";
+       phy-supply = <&vcc_3v3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac1m1_miim
+                    &gmac1m1_tx_bus2
+                    &gmac1m1_rx_bus2
+                    &gmac1m1_rgmii_clk
+                    &gmac1m1_rgmii_bus
+                    &gmac1m1_clkinout>;
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
+&hdmi {
+       avdd-0v9-supply = <&vdda0v9_image>;
+       avdd-1v8-supply = <&vcca1v8_image>;
+       status = "okay";
+};
+
+&hdmi_in {
+       hdmi_in_vp0: endpoint {
+               remote-endpoint = <&vp0_out_hdmi>;
+       };
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&hdmi_sound {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       vdd_cpu: regulator@1c {
+               compatible = "tcs,tcs4525";
+               reg = <0x1c>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1150000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       rk809: pmic@20 {
+               compatible = "rockchip,rk809";
+               reg = <0x20>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+               clock-output-names = "rk808-clkout1", "rk808-clkout2";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>, <&i2s1m0_mclk>;
+               system-power-controller;
+               vcc1-supply = <&vcc3v3_sys>;
+               vcc2-supply = <&vcc3v3_sys>;
+               vcc3-supply = <&vcc3v3_sys>;
+               vcc4-supply = <&vcc3v3_sys>;
+               vcc5-supply = <&vcc3v3_sys>;
+               vcc6-supply = <&vcc3v3_sys>;
+               vcc7-supply = <&vcc3v3_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc3v3_sys>;
+               wakeup-source;
+               #clock-cells = <1>;
+
+               regulators {
+                       vdd_logic: DCDC_REG1 {
+                               regulator-name = "vdd_logic";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       vdd_gpu: DCDC_REG2 {
+                               regulator-name = "vdd_gpu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       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;
+                               };
+                       };
+
+                       vdd_npu: DCDC_REG4 {
+                               regulator-name = "vdd_npu";
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: DCDC_REG5 {
+                               regulator-name = "vcc_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdda0v9_image: LDO_REG1 {
+                               regulator-name = "vdda0v9_image";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdda_0v9: LDO_REG2 {
+                               regulator-name = "vdda_0v9";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdda0v9_pmu: LDO_REG3 {
+                               regulator-name = "vdda0v9_pmu";
+                               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>;
+                               };
+                       };
+
+                       vccio_acodec: LDO_REG4 {
+                               regulator-name = "vccio_acodec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG5 {
+                               regulator-name = "vccio_sd";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_pmu: LDO_REG6 {
+                               regulator-name = "vcc3v3_pmu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG7 {
+                               regulator-name = "vcca_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcca1v8_pmu: LDO_REG8 {
+                               regulator-name = "vcca1v8_pmu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcca1v8_image: LDO_REG9 {
+                               regulator-name = "vcca1v8_image";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v3: SWITCH_REG1 {
+                               regulator-name = "vcc_3v3";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_sd: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_sd";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       eeprom: eeprom@50 {
+               compatible = "belling,bl24c16a", "atmel,24c16";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+};
+
+&i2s0_8ch {
+       status = "okay";
+};
+
+&i2s1_8ch {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
+       rockchip,trcm-sync-tx-only;
+       status = "okay";
+};
+
+&mdio1 {
+       rgmii_phy1: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <0x1>;
+               reset-assert-us = <20000>;
+               reset-deassert-us = <100000>;
+               reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&pcie2x1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_reset_h>;
+       reset-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
+&pinctrl {
+       bluetooth {
+               bt_reg_on_h: bt-reg-on-h {
+                       rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_wake_host_h: bt-wake-host-h {
+                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_host_wake_h: bt-host-wake-h {
+                       rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       cam {
+               vcc_cam_en: vcc_cam_en {
+                       rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       display {
+               vcc_mipi_en: vcc_mipi_en {
+                       rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       leds {
+               user_led2: user-led2 {
+                       rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pcie {
+               pcie_pwr_en: pcie-pwr-en {
+                       rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie_reset_h: pcie-reset-h {
+                       rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb {
+               vcc5v0_usb30_host_en: vcc5v0-usb30-host-en {
+                       rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc5v0_usb_otg_en: vcc5v0-usb-otg-en {
+                       rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       wifi {
+               wifi_host_wake_h: wifi-host-wake-h {
+                       rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               wifi_reg_on_h: wifi-reg-on-h {
+                       rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       pmuio1-supply = <&vcc3v3_pmu>;
+       pmuio2-supply = <&vcca1v8_pmu>;
+       vccio1-supply = <&vccio_acodec>;
+       vccio2-supply = <&vcc_1v8>;
+       vccio3-supply = <&vccio_sd>;
+       vccio4-supply = <&vcca1v8_pmu>;
+       vccio5-supply = <&vcc_3v3>;
+       vccio6-supply = <&vcc_3v3>;
+       vccio7-supply = <&vcc_3v3>;
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca_1v8>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       max-frequency = <200000000>;
+       mmc-hs200-1_8v;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+       vmmc-supply = <&vcc_3v3>;
+       vqmmc-supply = <&vcc_1v8>;
+       status = "okay";
+};
+
+&sdmmc0 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       disable-wp;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+       sd-uhs-sdr50;
+       vmmc-supply = <&vcc3v3_sys>;
+       vqmmc-supply = <&vccio_sd>;
+       status = "okay";
+};
+
+&sdmmc1 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cap-sdio-irq;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_clk &sdmmc1_cmd>;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc3v3_sys>;
+       vqmmc-supply = <&vcca1v8_pmu>;
+       status = "okay";
+};
+
+&sfc {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-max-frequency = <120000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+       };
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <1>;
+       rockchip,hw-tshut-polarity = <0>;
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1m0_ctsn &uart1m0_rtsn &uart1m0_xfer>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host0_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usb_host1_xhci {
+       status = "okay";
+};
+
+&usb2phy0 {
+       status = "okay";
+};
+
+&usb2phy0_host {
+       phy-supply = <&vcc5v0_usb30_host>;
+       status = "okay";
+};
+
+&usb2phy0_otg {
+       phy-supply = <&vcc5v0_usb_otg>;
+       status = "okay";
+};
+
+&usb2phy1 {
+       status = "okay";
+};
+
+&usb2phy1_host {
+       phy-supply = <&vcc5v0_usb30_host>;
+       status = "okay";
+};
+
+&usb2phy1_otg {
+       phy-supply = <&vcc5v0_usb30_host>;
+       status = "okay";
+};
+
+&vop {
+       assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+       assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+       status = "okay";
+};
+
+&vop_mmu {
+       status = "okay";
+};
+
+&vp0 {
+       vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+               reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+               remote-endpoint = <&hdmi_in_vp0>;
+       };
+};
index fdbf1c78324229b81715279e4182e39bb3cde176..fdbb4a6a19d85bcf13c4330648638180514970e9 100644 (file)
@@ -10,7 +10,7 @@
 #include "rk3566-soquartz.dtsi"
 
 / {
-       model = "PINE64 RK3566 SOQuartz on Blade carrier board";
+       model = "Pine64 SOQuartz on Blade carrier board";
        compatible = "pine64,soquartz-blade", "pine64,soquartz", "rockchip,rk3566";
 
        aliases {
index 6ed3fa4aee34f22a0b09f189000800331a49b2aa..2b6f0df477b67fe3b67718e4963b77dc4aee4432 100644 (file)
@@ -5,7 +5,7 @@
 #include "rk3566-soquartz.dtsi"
 
 / {
-       model = "Pine64 RK3566 SoQuartz with CM4-IO Carrier Board";
+       model = "Pine64 SOQuartz on CM4-IO carrier board";
        compatible = "pine64,soquartz-cm4io", "pine64,soquartz", "rockchip,rk3566";
 
        aliases {
index f2095dfa4eaf6efe2d4c46d2dd78f68fa266ff7f..9a6a63277c3dca7f95fd951a666b3bf3d9a7528e 100644 (file)
@@ -5,7 +5,7 @@
 #include "rk3566-soquartz.dtsi"
 
 / {
-       model = "PINE64 RK3566 SOQuartz on Model A carrier board";
+       model = "Pine64 SOQuartz on Model A carrier board";
        compatible = "pine64,soquartz-model-a", "pine64,soquartz", "rockchip,rk3566";
 
        aliases {
index bfb7b952f4c5e849ed243c53ff3abef5cfb3c4d8..dd4e9c1893c6125d553be151963ca021c4b80b55 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3566.dtsi"
 
 / {
-       model = "Pine64 RK3566 SoQuartz SOM";
+       model = "Pine64 SOQuartz system on module";
        compatible = "pine64,soquartz", "rockchip,rk3566";
 
        aliases {
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts b/arch/arm64/boot/dts/rockchip/rk3568-mecsbc.dts
new file mode 100644 (file)
index 0000000..c2dfffc
--- /dev/null
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3568.dtsi"
+
+/ {
+       model = "Protonic MECSBC";
+       compatible = "prt,mecsbc", "rockchip,rk3568";
+
+       aliases {
+               mmc0 = &sdhci;
+               mmc1 = &sdmmc0;
+       };
+
+       chosen: chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       tas2562-sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,name = "Speaker";
+               simple-audio-card,mclk-fs = <256>;
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s1_8ch>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&tas2562>;
+               };
+       };
+
+       vdd_gpu: regulator-vdd-gpu {
+               compatible = "pwm-regulator";
+               pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <915000>;
+               regulator-max-microvolt = <1000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-settling-time-up-us = <250>;
+               pwm-dutycycle-range = <0 100>; /* dutycycle inverted 0% => 0.915V */
+       };
+
+       p3v3: regulator-p3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "p3v3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       p1v8: regulator-p1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "p1v8";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       vcc_sd: regulator-sd {
+               compatible = "regulator-gpio";
+               enable-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+               regulator-name = "sdcard-gpio-supply";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               states = <1800000 0x1>, <3300000 0x0>;
+       };
+
+       vdd_npu: regulator-vdd-npu {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>;
+               regulator-name = "vdd_npu";
+               regulator-min-microvolt = <915000>;
+               regulator-max-microvolt = <1000000>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-settling-time-up-us = <250>;
+               pwm-dutycycle-range = <0 100>; /* dutycycle inverted 0% => 0.915V */
+       };
+};
+
+&combphy0 {
+       status = "okay";
+};
+
+&combphy1 {
+       status = "okay";
+};
+
+&combphy2 {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_cpu>;
+};
+
+&gmac1 {
+       assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+       assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru CLK_MAC1_2TOP>;
+       phy-handle = <&rgmii_phy1>;
+       phy-mode = "rgmii-id";
+       clock_in_out = "output";
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac1m1_miim
+                    &gmac1m1_tx_bus2
+                    &gmac1m1_rx_bus2
+                    &gmac1m1_rgmii_clk
+                    &gmac1m1_clkinout
+                    &gmac1m1_rgmii_bus>;
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
+&gpu_opp_table {
+       compatible = "operating-points-v2";
+
+       opp-200000000 {
+               opp-hz = /bits/ 64 <200000000>;
+               opp-microvolt = <915000>;
+       };
+
+       opp-300000000 {
+               opp-hz = /bits/ 64 <300000000>;
+               opp-microvolt = <915000>;
+       };
+
+       opp-400000000 {
+               opp-hz = /bits/ 64 <400000000>;
+               opp-microvolt = <915000>;
+       };
+
+       opp-600000000 {
+               opp-hz = /bits/ 64 <600000000>;
+               opp-microvolt = <920000>;
+       };
+
+       opp-700000000 {
+               opp-hz = /bits/ 64 <700000000>;
+               opp-microvolt = <950000>;
+       };
+
+       opp-800000000 {
+               opp-hz = /bits/ 64 <800000000>;
+               opp-microvolt = <1000000>;
+       };
+};
+
+&i2c0 {
+       status = "okay";
+
+       vdd_cpu: regulator@60 {
+               compatible = "fcs,fan53555";
+               reg = <0x60>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1150000>;
+               regulator-ramp-delay = <2300>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2m0_xfer>;
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3m0_xfer>;
+       status = "okay";
+
+       tas2562: amplifier@4c {
+               compatible = "ti,tas2562";
+               reg = <0x4c>;
+               #sound-dai-cells = <0>;
+               shutdown-gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
+               interrupt-parent = <&gpio1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_tas2562>;
+               interrupts = <RK_PD1 IRQ_TYPE_LEVEL_LOW>;
+               ti,imon-slot-no = <0>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+
+       temperature-sensor@48 {
+               compatible = "ti,tmp1075";
+               reg = <0x48>;
+       };
+
+       rtc@51 {
+               compatible = "nxp,pcf85363";
+               reg = <0x51>;
+               #clock-cells = <0>;
+               clock-output-names = "rtcic_32kout";
+       };
+};
+
+&i2s1_8ch {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s1m0_sclktx &i2s1m0_lrcktx &i2s1m0_sdi0 &i2s1m0_sdo0>;
+       rockchip,trcm-sync-tx-only;
+       status = "okay";
+};
+
+&mdio1 {
+       rgmii_phy1: ethernet-phy@2 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <0x2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&eth_phy1_rst>;
+               reset-assert-us = <20000>;
+               reset-deassert-us = <100000>;
+               reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&pcie2x1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie20m1_pins>;
+       reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&pcie30phy {
+       status = "okay";
+};
+
+&pcie3x2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie30x2m1_pins>;
+       reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&p3v3>;
+       status = "okay";
+};
+
+&pinctrl {
+       ethernet {
+               eth_phy1_rst: eth-phy1-rst {
+                       rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       tas2562 {
+               pinctrl_tas2562: tas2562 {
+                       rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       pmuio1-supply = <&p3v3>;
+       pmuio2-supply = <&p3v3>;
+       vccio1-supply = <&p1v8>;
+       vccio2-supply = <&p1v8>;
+       vccio3-supply = <&vcc_sd>;
+       vccio4-supply = <&p1v8>;
+       vccio5-supply = <&p3v3>;
+       vccio6-supply = <&p1v8>;
+       vccio7-supply = <&p3v3>;
+       status = "okay";
+};
+
+&pwm1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm1m0_pins>;
+};
+
+&pwm2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm2m0_pins>;
+};
+
+&saradc {
+       vref-supply = <&p1v8>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       max-frequency = <200000000>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+       vmmc-supply = <&p3v3>;
+       vqmmc-supply = <&p1v8>;
+       mmc-hs200-1_8v;
+       non-removable;
+       no-sd;
+       no-sdio;
+       status = "okay";
+};
+
+&sdmmc0 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+       sd-uhs-sdr50;
+       sd-uhs-sdr104;
+       vmmc-supply = <&p3v3>;
+       vqmmc-supply = <&vcc_sd>;
+       status = "okay";
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <1>;
+       rockchip,hw-tshut-polarity = <0>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host0_xhci {
+       dr_mode = "host";
+       extcon = <&usb2phy0>;
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usb_host1_xhci {
+       status = "okay";
+};
+
+&usb2phy0 {
+       status = "okay";
+};
+
+&usb2phy0_host {
+       status = "okay";
+};
+
+&usb2phy0_otg {
+       status = "okay";
+};
+
+&usb2phy1 {
+       status = "okay";
+};
+
+&usb2phy1_host {
+       status = "okay";
+};
+
+&usb2phy1_otg {
+       status = "okay";
+};
index a5e974ea659e2eb274d5ee65ebbecc61300db164..ebdedea15ad1605a05f278d52ad2f6cf8101c14a 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3568.dtsi"
 
 / {
-       model = "Radxa ROCK3 Model A";
+       model = "Radxa ROCK 3A";
        compatible = "radxa,rock3a", "rockchip,rk3568";
 
        aliases {
        status = "okay";
 };
 
+&sfc {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-max-frequency = <104000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+       };
+};
+
 &tsadc {
        rockchip,hw-tshut-mode = <1>;
        rockchip,hw-tshut-polarity = <0>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5-io-expander.dtso
new file mode 100644 (file)
index 0000000..ebcaeaf
--- /dev/null
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Device tree overlay for the WolfVision PF5 IO Expander board.
+ *
+ * Copyright (C) 2024 WolfVision GmbH.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/rk3568-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+&{/} {
+       gmac0_clkin: external-gmac0-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <50000000>;
+               clock-output-names = "gmac0_clkin";
+               #clock-cells = <0>;
+       };
+
+       usb_host_vbus: usb-host-vbus-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb_host_vbus_en>;
+               regulator-name = "usb_host_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v_in>;
+       };
+
+       vcc1v8_eth: vcc1v8-eth-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc1v8_eth_en>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "1v8_eth";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       vcc3v3_eth: vcc3v3-eth-regulator {
+               compatible = "regulator-fixed";
+               enable-active-low;
+               gpio = <&gpio0 RK_PC0 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc3v3_eth_enn>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "3v3_eth";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+};
+
+&gmac0 {
+       assigned-clocks = <&cru SCLK_GMAC0_RX_TX>,
+                         <&cru SCLK_GMAC0>;
+       assigned-clock-parents = <&cru SCLK_GMAC0_RMII_SPEED>,
+                                <&gmac0_clkin>;
+       clock_in_out = "input";
+       phy-handle = <&dp83826>;
+       phy-mode = "rmii";
+       phy-supply = <&vcc3v3_eth>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac0_miim
+                    &gmac0_clkinout
+                    &gmac0_rx_er
+                    &gmac0_rx_bus2
+                    &gmac0_tx_bus2>;
+       status = "okay";
+};
+
+&mdio0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       dp83826: ethernet-phy@0 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <0x0>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PD3 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&eth_wake_intn &eth_phy_rstn>;
+               reset-assert-us = <1000>;
+               reset-deassert-us = <2000>;
+               reset-gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_LOW>;
+               wakeup-source;
+       };
+};
+
+&pinctrl {
+       ethernet {
+               eth_wake_intn: eth-wake-intn-pinctrl {
+                       rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               eth_phy_rstn: eth-phy-rstn-pinctrl {
+                       rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc1v8_eth_en: vcc1v8-eth-en-pinctrl {
+                       rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc3v3_eth_enn: vcc3v3-eth-enn-pinctrl {
+                       rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb {
+               usb_host_vbus_en: usb-host-vbus-en-pinctrl {
+                       rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&usb_host1_xhci {
+       maximum-speed = "high-speed";
+       phys = <&usb2phy0_host>;
+       phy-names = "usb2-phy";
+       status = "okay";
+};
+
+&usb2phy0_host {
+       phy-supply = <&usb_host_vbus>;
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts b/arch/arm64/boot/dts/rockchip/rk3568-wolfvision-pf5.dts
new file mode 100644 (file)
index 0000000..170b14f
--- /dev/null
@@ -0,0 +1,528 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Device tree for the WolfVision PF5 mainboard.
+ *
+ * Copyright (C) 2024 WolfVision GmbH.
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/regulator/ti,tps62864.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+       model = "WolfVision PF5";
+       compatible = "wolfvision,rk3568-pf5", "rockchip,rk3568";
+
+       aliases {
+               ethernet0 = &gmac0;
+               mmc0 = &sdhci;
+               rtc0 = &pcf85623;
+               rtc1 = &rk809;
+       };
+
+       chosen: chosen {
+               stdout-path = "serial2:115200n8";
+       };
+
+       hdmi_tx: hdmi-tx-connector {
+               compatible = "hdmi-connector";
+               hdmi-pwr-supply = <&hdmi_tx_5v>;
+               type = "a";
+
+               port {
+                       hdmi_tx_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_out>;
+                       };
+               };
+       };
+
+       hdmi_tx_5v: hdmi-tx-5v-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hdmi_tx_5v_en>;
+               regulator-name = "hdmi_tx_5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v_in>;
+       };
+
+       pdm_codec: pdm-codec {
+               compatible = "dmic-codec";
+               num-channels = <1>;
+               #sound-dai-cells = <0>;
+       };
+
+       pdm_sound: pdm-sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "microphone";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&pdm>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&pdm_codec>;
+               };
+       };
+
+       vcc12v_cam: vcc12v-cam-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio2 RK_PD1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc12v_cam_en>;
+               regulator-name = "12v_cam";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               vin-supply = <&vcc12v_in>;
+       };
+
+       vcc12v_in: vcc12v-in-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "12v_in";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       vcc3v8_cam: vcc3v8-cam-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc3v8_cam_en>;
+               regulator-name = "3v8_cam";
+               regulator-min-microvolt = <3800000>;
+               regulator-max-microvolt = <3800000>;
+               vin-supply = <&vcc5v_in>;
+       };
+
+       vcc3v3_sys: vcc3v3-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "3v3_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc5v_in>;
+       };
+
+       vcc5v_in: vcc5v-in-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "5v_in";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc12v_in>;
+       };
+};
+
+&combphy0 {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu1 {
+       cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu2 {
+       cpu-supply = <&vcc0v9_cpu>;
+};
+
+&cpu3 {
+       cpu-supply = <&vcc0v9_cpu>;
+};
+
+&gpu {
+       mali-supply = <&vcc0v9_gpu>;
+       status = "okay";
+};
+
+&hdmi {
+       avdd-0v9-supply = <&vcc0v9a_image>;
+       avdd-1v8-supply = <&vcc1v8a_image>;
+       status = "okay";
+};
+
+&hdmi_in {
+       hdmi_in_vp0: endpoint {
+               remote-endpoint = <&vp0_out_hdmi>;
+       };
+};
+
+&hdmi_out {
+       hdmi_tx_out: endpoint {
+               remote-endpoint = <&hdmi_tx_in>;
+       };
+};
+
+&i2c0 {
+       status = "okay";
+
+       rk809: pmic@20 {
+               compatible = "rockchip,rk809";
+               reg = <0x20>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               vcc1-supply = <&vcc5v_in>;
+               vcc2-supply = <&vcc5v_in>;
+               vcc3-supply = <&vcc5v_in>;
+               vcc4-supply = <&vcc5v_in>;
+               vcc5-supply = <&vcc3v3_sys>;
+               vcc6-supply = <&vcc5v_in>;
+               vcc7-supply = <&vcc3v3_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc3v3_sys>;
+               wakeup-source;
+
+               regulators {
+                       vcc0v9_logic: DCDC_REG1 {
+                               regulator-name = "0v9_logic";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc0v9_gpu: DCDC_REG2 {
+                               regulator-name = "0v9_gpu";
+                               regulator-always-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v1_ddr4: DCDC_REG3 {
+                               regulator-name = "1v1_ddr4";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <0x2>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc0v9_npu: DCDC_REG4 {
+                               regulator-name = "0v9_npu";
+                               regulator-always-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8: DCDC_REG5 {
+                               regulator-name = "1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc0v9a_image: LDO_REG1 {
+                               regulator-name = "0v9a_image";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc0v9a: LDO_REG2 {
+                               regulator-name = "0v9a";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc0v9a_pmu: LDO_REG3 {
+                               regulator-name = "0v9a_pmu";
+                               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>;
+                               };
+                       };
+
+                       vcc3v3_acodec: LDO_REG4 {
+                               regulator-name = "3v3_acodec";
+                               regulator-always-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_sd: LDO_REG5 {
+                               regulator-name = "3v3_sd";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_pmu: LDO_REG6 {
+                               regulator-name = "3v3_pmu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc1v8a: LDO_REG7 {
+                               regulator-name = "1v8a";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8a_pmu: LDO_REG8 {
+                               regulator-name = "1v8a_pmu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc1v8a_image: LDO_REG9 {
+                               regulator-name = "1v8a_image";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_sw: SWITCH_REG1 {
+                               regulator-name = "3v3_sw";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       regulator@42 {
+               compatible = "ti,tps62869";
+               reg = <0x42>;
+
+               regulators {
+                       vcc0v9_cpu: SW {
+                               regulator-name = "0v9_cpu";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <TPS62864_MODE_FPWM>;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1150000>;
+                               vin-supply = <&vcc5v_in>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       pcf85623: rtc@51 {
+               compatible = "nxp,pcf85263";
+               reg = <0x51>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&clk32k_in>;
+               quartz-load-femtofarads = <12500>;
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3m0_xfer>;
+};
+
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4m1_xfer>;
+};
+
+&pdm {
+       pinctrl-0 = <&pdmm0_clk
+                    &pdmm0_sdi0>;
+       status = "okay";
+};
+
+&pinctrl {
+       cam {
+               vcc12v_cam_en: vcc12v-cam-en-pinctrl {
+                       rockchip,pins = <2 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc3v8_cam_en: vcc3v8-cam-en-pinctrl {
+                       rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       hdmitx {
+               hdmi_tx_5v_en: hdmi-tx-5v-en-pinctrl {
+                       rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l-pinctrl {
+                       rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       pmuio1-supply = <&vcc3v3_pmu>;
+       pmuio2-supply = <&vcc3v3_pmu>;
+       vccio1-supply = <&vcc3v3_acodec>;
+       vccio2-supply = <&vcc1v8>;
+       vccio3-supply = <&vcc3v3_sd>;
+       vccio4-supply = <&vcc1v8>;
+       vccio5-supply = <&vcc1v8>;
+       vccio6-supply = <&vcc3v3_sw>;
+       vccio7-supply = <&vcc3v3_sw>;
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcc1v8a>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       max-frequency = <200000000>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+       vmmc-supply = <&vcc3v3_sw>;
+       vqmmc-supply = <&vcc1v8>;
+       status = "okay";
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <1>;
+       rockchip,hw-tshut-polarity = <0>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_xhci {
+       dr_mode = "peripheral";
+       /* The following quirks are required since the bInterval is 1 and we
+        * handle steady ISOC streaming. See Usecase 3 in commit 729dcffd1ed3
+        * ("usb: dwc3: gadget: Add support for disabling U1 and U2 entries").
+        */
+       snps,dis-u1-entry-quirk;
+       snps,dis-u2-entry-quirk;
+       /*
+        * Without this quirk the available fifosize seems to be miscalculated
+        * in cases where many endpoints are used. In one particular situation
+        * 8 IN EPs and 3 OUT EPs where selected and lead to stalled transfers
+        * without the resize quirk.
+        */
+       tx-fifo-resize;
+
+       status = "okay";
+};
+
+&usb2phy0 {
+       status = "okay";
+};
+
+&usb2phy0_otg {
+       status = "okay";
+};
+
+&vop {
+       assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP2>;
+       assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+       status = "okay";
+};
+
+&vop_mmu {
+       status = "okay";
+};
+
+&vp0 {
+       vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+               reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+               remote-endpoint = <&hdmi_in_vp0>;
+       };
+};
index 92f96ec01385d9cbf8be0300ce7b77b8d8f13341..d8543b5557ee7202af6554cf55eccc9a7eeba25f 100644 (file)
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <128>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l3_cache>;
                };
 
                cpu1: cpu@100 {
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <128>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l3_cache>;
                };
 
                cpu2: cpu@200 {
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <128>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l3_cache>;
                };
 
                cpu3: cpu@300 {
                        #cooling-cells = <2>;
                        enable-method = "psci";
                        operating-points-v2 = <&cpu0_opp_table>;
+                       i-cache-size = <0x8000>;
+                       i-cache-line-size = <64>;
+                       i-cache-sets = <128>;
+                       d-cache-size = <0x8000>;
+                       d-cache-line-size = <64>;
+                       d-cache-sets = <128>;
+                       next-level-cache = <&l3_cache>;
                };
        };
 
+       /*
+        * There are no private per-core L2 caches, but only the
+        * L3 cache that appears to the CPU cores as L2 caches
+        */
+       l3_cache: l3-cache {
+               compatible = "cache";
+               cache-level = <2>;
+               cache-unified;
+               cache-size = <0x80000>;
+               cache-line-size = <64>;
+               cache-sets = <512>;
+       };
+
        cpu0_opp_table: opp-table-0 {
                compatible = "operating-points-v2";
                opp-shared;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
new file mode 100644 (file)
index 0000000..98c622b
--- /dev/null
@@ -0,0 +1,721 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "rk3588.dtsi"
+
+/ {
+       model = "ArmSoM Sige7";
+       compatible = "armsom,sige7", "rockchip,rk3588";
+
+       aliases {
+               mmc0 = &sdhci;
+               mmc1 = &sdmmc;
+       };
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       analog-sound {
+               compatible = "audio-graph-card";
+               dais = <&i2s0_8ch_p0>;
+               label = "rk3588-es8316";
+               hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hp_detect>;
+               routing = "MIC2", "Mic Jack",
+                         "Headphones", "HPOL",
+                         "Headphones", "HPOR";
+               widgets = "Microphone", "Mic Jack",
+                         "Headphone", "Headphones";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_rgb_g>;
+
+               led_green: led-0 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_STATUS;
+                       gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led_red: led-1 {
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_STATUS;
+                       gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "none";
+               };
+       };
+
+       fan: pwm-fan {
+               compatible = "pwm-fan";
+               cooling-levels = <0 95 145 195 255>;
+               fan-supply = <&vcc5v0_sys>;
+               pwms = <&pwm1 0 50000 0>;
+               #cooling-cells = <2>;
+       };
+
+       vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_pcie2x1l2";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <5000>;
+               vin-supply = <&vcc_3v3_s3>;
+       };
+
+       vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+               regulator-name = "vcc3v3_pcie30";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <5000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_host";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       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>;
+       };
+
+       vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_1v1_nldo_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1100000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+};
+
+&combphy0_ps {
+       status = "okay";
+};
+
+&combphy1_ps {
+       status = "okay";
+};
+
+&combphy2_psu {
+       status = "okay";
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0m2_xfer>;
+       status = "okay";
+
+       vdd_cpu_big0_s0: regulator@42 {
+               compatible = "rockchip,rk8602";
+               reg = <0x42>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big0_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_cpu_big1_s0: regulator@43 {
+               compatible = "rockchip,rk8603", "rockchip,rk8602";
+               reg = <0x43>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big1_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c6 {
+       status = "okay";
+
+       hym8563: rtc@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <0>;
+               clock-output-names = "hym8563";
+               pinctrl-names = "default";
+               pinctrl-0 = <&hym8563_int>;
+               wakeup-source;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+
+       es8316: audio-codec@11 {
+               compatible = "everest,es8316";
+               reg = <0x11>;
+               assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+               assigned-clock-rates = <12288000>;
+               clocks = <&cru I2S0_8CH_MCLKOUT>;
+               clock-names = "mclk";
+               #sound-dai-cells = <0>;
+
+               port {
+                       es8316_p0_0: endpoint {
+                               remote-endpoint = <&i2s0_8ch_p0_0>;
+                       };
+               };
+       };
+};
+
+&i2s0_8ch {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s0_lrck
+                    &i2s0_mclk
+                    &i2s0_sclk
+                    &i2s0_sdi0
+                    &i2s0_sdo0>;
+       status = "okay";
+
+       i2s0_8ch_p0: port {
+               i2s0_8ch_p0_0: endpoint {
+                       dai-format = "i2s";
+                       mclk-fs = <256>;
+                       remote-endpoint = <&es8316_p0_0>;
+               };
+       };
+};
+
+/* phy1 - right ethernet port */
+&pcie2x1l0 {
+       reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+/* phy2 - WiFi */
+&pcie2x1l1 {
+       reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+/* phy0 - left ethernet port */
+&pcie2x1l2 {
+       reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&pcie30phy {
+       status = "okay";
+};
+
+&pcie3x4 {
+       reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie30>;
+       status = "okay";
+};
+
+&pinctrl {
+       hym8563 {
+               hym8563_int: hym8563-int {
+                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       leds {
+               led_rgb_g: led-rgb-g {
+                       rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+               led_rgb_r: led-rgb-r {
+                       rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       sound {
+               hp_detect: hp-detect {
+                       rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&avcc_1v8_s0>;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       no-sdio;
+       no-sd;
+       non-removable;
+       mmc-hs200-1_8v;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       disable-wp;
+       max-frequency = <200000000>;
+       no-sdio;
+       no-mmc;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc_3v3_s3>;
+       vqmmc-supply = <&vccio_sd_s0>;
+       status = "okay";
+};
+
+&spi2 {
+       assigned-clocks = <&cru CLK_SPI2>;
+       assigned-clock-rates = <200000000>;
+       num-cs = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+       status = "okay";
+
+       pmic@0 {
+               compatible = "rockchip,rk806";
+               spi-max-frequency = <1000000>;
+               reg = <0x0>;
+
+               interrupt-parent = <&gpio0>;
+               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+                           <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+               system-power-controller;
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc5-supply = <&vcc5v0_sys>;
+               vcc6-supply = <&vcc5v0_sys>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc5v0_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+               vcc10-supply = <&vcc5v0_sys>;
+               vcc11-supply = <&vcc_2v0_pldo_s3>;
+               vcc12-supply = <&vcc5v0_sys>;
+               vcc13-supply = <&vcc_1v1_nldo_s3>;
+               vcc14-supply = <&vcc_1v1_nldo_s3>;
+               vcca-supply = <&vcc5v0_sys>;
+
+               rk806_dvs1_null: dvs1-null-pins {
+                       pins = "gpio_pwrctrl1";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs2_null: dvs2-null-pins {
+                       pins = "gpio_pwrctrl2";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs3_null: dvs3-null-pins {
+                       pins = "gpio_pwrctrl3";
+                       function = "pin_fun0";
+               };
+
+               regulators {
+                       vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_gpu_s0";
+                               regulator-enable-ramp-delay = <400>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_cpu_lit_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_log_s0: dcdc-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_log_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_vdenc_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_ddr_s0: dcdc-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_ddr_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       vdd2_ddr_s3: dcdc-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vdd2_ddr_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_2v0_pldo_s3: dcdc-reg7 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <2000000>;
+                               regulator-max-microvolt = <2000000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_2v0_pldo_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <2000000>;
+                               };
+                       };
+
+                       vcc_3v3_s3: dcdc-reg8 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_3v3_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vddq_ddr_s0: dcdc-reg9 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vddq_ddr_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s3: dcdc-reg10 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avcc_1v8_s0: pldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "avcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s0: pldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avdd_1v2_s0: pldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "avdd_1v2_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v3_s0: pldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vcc_3v3_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vccio_sd_s0: pldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vccio_sd_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       pldo6_s3: pldo-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "pldo6_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_0v75_s3: nldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_ddr_pll_s0: nldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_ddr_pll_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       avdd_0v75_s0: nldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "avdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v85_s0: nldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_0v85_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v75_s0: nldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       status = "okay";
+};
+
+&u2phy3 {
+       status = "okay";
+};
+
+&u2phy3_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-0 = <&uart2m0_xfer>;
+       status = "okay";
+};
+
+&usbdp_phy1 {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usb_host1_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
index 94ecb9b4f98f88c6ec0f93ff839f6a594eb75c19..fde8b228f2c7c92096ceab84125fa1d3b1d205fd 100644 (file)
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-0 = <&i2c0m2_xfer>;
        status = "okay";
                vcca-supply = <&vcc5v0_sys>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
index c0d4a15323e292b3f458702876a1d28291ebe88a..709d348cf06b81781f68fdcbb776ca8b3742941a 100644 (file)
                pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
                            <&rk806_dvs2_null>, <&rk806_dvs3_null>;
 
+               system-power-controller;
+
                vcc1-supply = <&vcc5v0_sys>;
                vcc2-supply = <&vcc5v0_sys>;
                vcc3-supply = <&vcc5v0_sys>;
                #gpio-cells = <2>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
index 963e880ccc1219461ebe98ce38a9abd075c7d8a7..7b131789835812cc1f54a79fbca6218c63ca184a 100644 (file)
        status = "okay";
 };
 
+&combphy2_psu {
+       status = "okay";
+};
+
 &i2c6 {
        status = "okay";
 
 &usb_host1_ohci {
        status = "okay";
 };
+
+&usb_host2_xhci {
+       status = "okay";
+};
index de30c2632b8e5fc8cc6d89272269353676b1e1a3..7be2190244bafb2fabdd7b2ab37aee1d16351d72 100644 (file)
@@ -9,6 +9,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
 #include "rk3588.dtsi"
 
 / {
                vin-supply = <&avcc_1v8_s0>;
        };
 
+       vbus5v0_typec: vbus5v0-typec-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&typec5v_pwren>;
+               regulator-name = "vbus5v0_typec";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v0_usb>;
+       };
+
        vcc12v_dcin: vcc12v-dcin-regulator {
                compatible = "regulator-fixed";
                regulator-name = "vcc12v_dcin";
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       sram-supply = <&vdd_gpu_mem_s0>;
+       status = "okay";
+};
+
 &i2c2 {
        status = "okay";
 
+       usbc0: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usbc0_int>;
+               vbus-supply = <&vbus5v0_typec>;
+               status = "okay";
+
+               usb_con: connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       data-role = "dual";
+                       op-sink-microwatt = <1000000>;
+                       power-role = "dual";
+                       sink-pdos =
+                               <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+                       source-pdos =
+                               <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+                       try-power-role = "source";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       usbc0_orien_sw: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_orientation_switch>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       usbc0_role_sw: endpoint {
+                                               remote-endpoint = <&dwc3_0_role_switch>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+
+                                       dp_altmode_mux: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+                                       };
+                               };
+                       };
+               };
+       };
+
        hym8563: rtc@51 {
                compatible = "haoyu,hym8563";
                reg = <0x51>;
                        rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
+
+       usb-typec {
+               typec5v_pwren: typec5v-pwren {
+                       rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               usbc0_int: usbc0-int {
+                       rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
 };
 
 &pwm2 {
 
                regulators {
                        vdd_gpu_s0: dcdc-reg1 {
+                               /* regulator coupling requires always-on */
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <550000>;
                                regulator-max-microvolt = <950000>;
                                regulator-ramp-delay = <12500>;
                                regulator-name = "vdd_gpu_s0";
                                regulator-enable-ramp-delay = <400>;
+                               regulator-coupled-with = <&vdd_gpu_mem_s0>;
+                               regulator-coupled-max-spread = <10000>;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
                        };
 
                        vdd_gpu_mem_s0: dcdc-reg5 {
+                               /* regulator coupling requires always-on */
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <675000>;
                                regulator-max-microvolt = <950000>;
                                regulator-ramp-delay = <12500>;
                                regulator-enable-ramp-delay = <400>;
                                regulator-name = "vdd_gpu_mem_s0";
+                               regulator-coupled-with = <&vdd_gpu_s0>;
+                               regulator-coupled-max-spread = <10000>;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
        status = "okay";
 };
 
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
 &usb_host1_ohci {
        status = "okay";
 };
+
+&usbdp_phy0 {
+       mode-switch;
+       orientation-switch;
+       sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
+       sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usbdp_phy0_orientation_switch: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&usbc0_orien_sw>;
+               };
+
+               usbdp_phy0_dp_altmode_mux: endpoint@1 {
+                       reg = <1>;
+                       remote-endpoint = <&dp_altmode_mux>;
+               };
+       };
+};
+
+&usbdp_phy1 {
+       /*
+        * USBDP PHY1 is wired to a female USB3 Type-A connector. Additionally
+        * the differential pairs 2+3 and the aux channel are wired to a RTD2166,
+        * which converts the DP signal into VGA. This is exposed on the
+        * board via a female VGA connector.
+        */
+       rockchip,dp-lane-mux = <2 3>;
+       status = "okay";
+};
+
+&usb_host0_xhci {
+       dr_mode = "otg";
+       usb-role-switch;
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dwc3_0_role_switch: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&usbc0_role_sw>;
+               };
+       };
+};
+
+&usb_host1_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-fet3588-c.dtsi
new file mode 100644 (file)
index 0000000..47e64d5
--- /dev/null
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "rk3588.dtsi"
+
+/ {
+       compatible = "forlinx,fet3588-c", "rockchip,rk3588";
+
+       aliases {
+               mmc0 = &sdhci;
+       };
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&led_rgb_b>;
+
+               io-led {
+                       function = LED_FUNCTION_STATUS;
+                       color = <LED_COLOR_ID_BLUE>;
+                       gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "pcie20_avdd0v85";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <850000>;
+               regulator-max-microvolt = <850000>;
+               vin-supply = <&vdd_0v85_s0>;
+       };
+
+       pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "pcie20_avdd1v8";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&avcc_1v8_s0>;
+       };
+
+       pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "pcie30_avdd0v75";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <750000>;
+               regulator-max-microvolt = <750000>;
+               vin-supply = <&avdd_0v75_s0>;
+       };
+
+       pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "pcie30_avdd1v8";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&avcc_1v8_s0>;
+       };
+
+       vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_1v1_nldo_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1100000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc4v0_sys: vcc4v0-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc4v0_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <4000000>;
+               regulator-max-microvolt = <4000000>;
+               vin-supply = <&vcc12v_dcin>;
+       };
+};
+
+&combphy0_ps {
+       status = "okay";
+};
+
+&combphy1_ps {
+       status = "okay";
+};
+
+&combphy2_psu {
+       status = "okay";
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+       mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+       mem-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+       mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+       mem-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+       mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+       mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+       mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+       mem-supply = <&vdd_cpu_lit_mem_s0>;
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0m2_xfer>;
+       status = "okay";
+
+       vdd_cpu_big0_s0: regulator@42 {
+               compatible = "rockchip,rk8602";
+               reg = <0x42>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big0_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc4v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_cpu_big1_s0: regulator@43 {
+               compatible = "rockchip,rk8603", "rockchip,rk8602";
+               reg = <0x43>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big1_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc4v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1m2_xfer>;
+
+       vdd_npu_s0: regulator@42 {
+               compatible = "rockchip,rk8602";
+               reg = <0x42>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_npu_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <950000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc4v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&pinctrl {
+       leds {
+               led_rgb_b: led-rgb-b {
+                       rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       no-sdio;
+       no-sd;
+       non-removable;
+       status = "okay";
+};
+
+&spi2 {
+       status = "okay";
+       assigned-clocks = <&cru CLK_SPI2>;
+       assigned-clock-rates = <200000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+       num-cs = <1>;
+
+       pmic@0 {
+               compatible = "rockchip,rk806";
+               spi-max-frequency = <1000000>;
+               reg = <0x0>;
+
+               interrupt-parent = <&gpio0>;
+               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+                           <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+               system-power-controller;
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc5-supply = <&vcc5v0_sys>;
+               vcc6-supply = <&vcc5v0_sys>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc5v0_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+               vcc10-supply = <&vcc5v0_sys>;
+               vcc11-supply = <&vcc_2v0_pldo_s3>;
+               vcc12-supply = <&vcc5v0_sys>;
+               vcc13-supply = <&vcc_1v1_nldo_s3>;
+               vcc14-supply = <&vcc_1v1_nldo_s3>;
+               vcca-supply = <&vcc5v0_sys>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               rk806_dvs1_null: dvs1-null-pins {
+                       pins = "gpio_pwrctrl1";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs2_null: dvs2-null-pins {
+                       pins = "gpio_pwrctrl2";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs3_null: dvs3-null-pins {
+                       pins = "gpio_pwrctrl3";
+                       function = "pin_fun0";
+               };
+
+               regulators {
+                       vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_gpu_s0";
+                               regulator-enable-ramp-delay = <400>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_cpu_lit_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_log_s0: dcdc-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_log_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_vdenc_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_ddr_s0: dcdc-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_ddr_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       vdd2_ddr_s3: dcdc-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vdd2_ddr_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_2v0_pldo_s3: dcdc-reg7 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <2000000>;
+                               regulator-max-microvolt = <2000000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vdd_2v0_pldo_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <2000000>;
+                               };
+                       };
+
+                       vcc_3v3_s3: dcdc-reg8 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_3v3_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vddq_ddr_s0: dcdc-reg9 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vddq_ddr_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s3: dcdc-reg10 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avcc_1v8_s0: pldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "avcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s0: pldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avdd_1v2_s0: pldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "avdd_1v2_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v3_s0: pldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vcc_3v3_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vccio_sd_s0: pldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vccio_sd_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       pldo6_s3: pldo-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "pldo6_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_0v75_s3: nldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_ddr_pll_s0: nldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_ddr_pll_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       avdd_0v75_s0: nldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "avdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v85_s0: nldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_0v85_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v75_s0: nldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&tsadc {
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-0 = <&uart2m0_xfer>;
+       status = "okay";
+};
index 39d65002add1e11e81bb0d660fd7f5ff90e4cdf7..31d2f8994f8513e4094840223ff01718f9fce731 100644 (file)
                };
        };
 
+       /*
+        * 100MHz reference clock for PCIe peripherals from PI6C557-05BLE
+        * clock generator.
+        * The clock output is gated via the OE pin on the clock generator.
+        * This is modeled as a fixed-clock plus a gpio-gate-clock.
+        */
+       pcie_refclk_gen: pcie-refclk-gen-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <100000000>;
+       };
+
+       pcie_refclk: pcie-refclk-clock {
+               compatible = "gpio-gate-clock";
+               clocks = <&pcie_refclk_gen>;
+               #clock-cells = <0>;
+               enable-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>; /* PCIE30X4_CLKREQN_M0 */
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie30x4_clkreqn_m0>;
+       };
+
        pps {
                compatible = "pps-gpio";
                gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
        };
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-0 = <&i2c0m2_xfer>;
        status = "okay";
        status = "okay";
 };
 
+&pcie30phy {
+       status = "okay";
+};
+
+&pcie3x4 {
+       /*
+        * The board has a gpio-controlled "pcie_refclk" generator,
+        * so add it to the list of clocks.
+        */
+       clocks = <&cru ACLK_PCIE_4L_MSTR>, <&cru ACLK_PCIE_4L_SLV>,
+                <&cru ACLK_PCIE_4L_DBI>, <&cru PCLK_PCIE_4L>,
+                <&cru CLK_PCIE_AUX0>, <&cru CLK_PCIE4L_PIPE>,
+                <&pcie_refclk>;
+       clock-names = "aclk_mst", "aclk_slv",
+                     "aclk_dbi", "pclk",
+                     "aux", "pipe",
+                     "ref";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie30x4_waken_m0 &pcie30x4_perstn_m0>;
+       reset-gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_HIGH>; /* PCIE30X4_PERSTN_M0 */
+       vpcie3v3-supply = <&vcc3v3_mdot2>;
+       status = "okay";
+};
+
 &pinctrl {
        emmc {
                emmc_reset: emmc-reset {
                        rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
+
+       pcie30x4 {
+               pcie30x4_clkreqn_m0: pcie30x4-clkreqn-m0 {
+                       rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie30x4_perstn_m0: pcie30x4-perstn-m0 {
+                       rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie30x4_waken_m0: pcie30x4-waken-m0 {
+                       rockchip,pins = <0 RK_PC7 12 &pcfg_pull_none>;
+               };
+       };
 };
 
 &saradc {
                vcca-supply = <&vcc5v0_sys>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
new file mode 100644 (file)
index 0000000..009566d
--- /dev/null
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+#include "rk3588-fet3588-c.dtsi"
+
+/ {
+       model = "Forlinx OK3588-C Board";
+       compatible = "forlinx,ok3588-c", "forlinx,fet3588-c", "rockchip,rk3588";
+
+       aliases {
+               ethernet0 = &gmac0;
+               ethernet1 = &gmac1;
+               mmc1 = &sdmmc;
+       };
+
+       adc-keys-0 {
+               compatible = "adc-keys";
+               io-channels = <&saradc 0>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+               poll-interval = <100>;
+
+               button-maskrom {
+                       label = "Maskrom";
+                       linux,code = <KEY_SETUP>;
+                       press-threshold-microvolt = <400>;
+               };
+       };
+
+       adc-keys-1 {
+               compatible = "adc-keys";
+               io-channels = <&saradc 1>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+               poll-interval = <100>;
+
+               button-volume-up {
+                       label = "V+/Recovery";
+                       linux,code = <KEY_VOLUMEUP>;
+                       press-threshold-microvolt = <17000>;
+               };
+
+               button-volume-down {
+                       label = "V-";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       press-threshold-microvolt = <417000>;
+               };
+
+               button-menu {
+                       label = "Menu";
+                       linux,code = <KEY_MENU>;
+                       press-threshold-microvolt = <890000>;
+               };
+
+               button-escape {
+                       label = "ESC";
+                       linux,code = <KEY_ESC>;
+                       press-threshold-microvolt = <1235000>;
+               };
+       };
+
+       fan: pwm-fan {
+               compatible = "pwm-fan";
+               cooling-levels = <0 95 145 195 255>;
+               fan-supply = <&vcc12v_dcin>;
+               pwms = <&pwm2 0 50000 0>;
+               #cooling-cells = <2>;
+       };
+
+       sound {
+               compatible = "simple-audio-card";
+               pinctrl-names = "default";
+               pinctrl-0 = <&hp_detect>;
+               simple-audio-card,name = "RK3588 OK3588-C Audio";
+               simple-audio-card,bitclock-master = <&masterdai>;
+               simple-audio-card,format = "i2s";
+               simple-audio-card,frame-master = <&masterdai>;
+               simple-audio-card,hp-det-gpio = <&gpio1 RK_PB2 GPIO_ACTIVE_HIGH>;
+               simple-audio-card,mclk-fs = <256>;
+               simple-audio-card,pin-switches = "Headphones", "Speaker";
+               simple-audio-card,widgets =
+                       "Headphones", "Headphones",
+                       "Speaker", "Speaker",
+                       "Microphone", "Internal Microphone",
+                       "Microphone", "Headset Microphone";
+               simple-audio-card,routing =
+                       "Headphones", "LHP",
+                       "Headphones", "RHP",
+                       "Speaker", "LSPK",
+                       "Speaker", "RSPK",
+                       "LMICP", "Headset Microphone",
+                       "RMICP", "Internal Microphone";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s0_8ch>;
+               };
+
+               masterdai: simple-audio-card,codec {
+                       sound-dai = <&nau8822>;
+               };
+       };
+
+       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>;
+       };
+
+       vcc1v8_sys: vcc1v8-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_pcie2x1l0";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <50000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_pcie2x1l2";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <5000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc3v3_pcie30: vcc3v3_pcie30-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_pcie30";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc3v3_sys: vcc3v3-sys-regulator {
+               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>;
+       };
+
+       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>;
+       };
+};
+
+&gmac0 {
+       clock_in_out = "output";
+       phy-handle = <&rgmii_phy0>;
+       phy-mode = "rgmii-rxid";
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac0_miim
+                    &gmac0_tx_bus2
+                    &gmac0_rx_bus2
+                    &gmac0_rgmii_clk
+                    &gmac0_rgmii_bus>;
+       tx_delay = <0x44>;
+       rx_delay = <0x00>;
+       status = "okay";
+};
+
+&gmac1 {
+       clock_in_out = "output";
+       phy-handle = <&rgmii_phy1>;
+       phy-mode = "rgmii-rxid";
+       pinctrl-names = "default";
+       pinctrl-0 = <&gmac1_miim
+                    &gmac1_tx_bus2
+                    &gmac1_rx_bus2
+                    &gmac1_rgmii_clk
+                    &gmac1_rgmii_bus>;
+       tx_delay = <0x44>;
+       rx_delay = <0x00>;
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+
+       tca6424a: gpio@23 {
+               compatible = "ti,tca6424";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               interrupt-parent = <&gpio1>;
+               interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&tca6424a_int>;
+               vcc-supply = <&vcc3v3_sys>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c5m2_xfer>;
+
+       pcf8563: rtc@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+
+       nau8822: audio-codec@1a {
+               compatible = "nuvoton,nau8822";
+               reg = <0x1a>;
+               clocks = <&cru I2S0_8CH_MCLKOUT>;
+               clock-names = "mclk";
+               assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+               assigned-clock-rates = <12288000>;
+               #sound-dai-cells = <0>;
+       };
+};
+
+&i2s0_8ch {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s0_lrck
+                    &i2s0_mclk
+                    &i2s0_sclk
+                    &i2s0_sdi0
+                    &i2s0_sdo0>;
+       status = "okay";
+};
+
+&mdio0 {
+       rgmii_phy0: ethernet-phy@1 {
+               /* RTL8211F */
+               compatible = "ethernet-phy-id001c.c916",
+                            "ethernet-phy-ieee802.3-c22";
+               reg = <0x1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&rtl8211f_0_rst>;
+               reset-assert-us = <20000>;
+               reset-deassert-us = <100000>;
+               reset-gpios = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&mdio1 {
+       rgmii_phy1: ethernet-phy@2 {
+               /* RTL8211F */
+               compatible = "ethernet-phy-id001c.c916",
+                            "ethernet-phy-ieee802.3-c22";
+               reg = <0x2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&rtl8211f_1_rst>;
+               reset-assert-us = <20000>;
+               reset-deassert-us = <100000>;
+               reset-gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&pcie2x1l0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie2_0_rst>;
+       reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+       status = "okay";
+};
+
+&pcie2x1l2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie2_2_rst>;
+       reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
+       status = "okay";
+};
+
+&pcie30phy {
+       status = "okay";
+};
+
+&pcie3x4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie3_rst>;
+       reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie30>;
+       status = "okay";
+};
+
+&pinctrl {
+       pcie2 {
+               pcie2_0_rst: pcie2-0-rst {
+                       rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie2_2_rst: pcie2-2-rst {
+                       rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pcie3 {
+               pcie3_rst: pcie3-rst {
+                       rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       rtl8211f {
+               rtl8211f_0_rst: rtl8211f-0-rst {
+                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+               rtl8211f_1_rst: rtl8211f-1-rst {
+                       rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       sound {
+               hp_detect: hp-detect {
+                       rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       tca6424a {
+               tca6424a_int: tca6424a-int {
+                       rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&avcc_1v8_s0>;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       max-frequency = <150000000>;
+       no-sdio;
+       no-mmc;
+       sd-uhs-sdr104;
+       vqmmc-supply = <&vccio_sd_s0>;
+       status = "okay";
+};
+
+&u2phy2 {
+       status = "okay";
+};
+
+&u2phy2_host {
+       status = "okay";
+};
+
+&u2phy3 {
+       status = "okay";
+};
+
+&u2phy3_host {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
index 22bbfbe729c11b6e0d30cd88a5fa144ba52a22e6..b4f22d95ac0e1c0a2ac2dbf6f3d154f887275870 100644 (file)
@@ -13,7 +13,7 @@
 #include "rk3588.dtsi"
 
 / {
-       model = "PINE64 QuartzPro64";
+       model = "Pine64 QuartzPro64";
        compatible = "pine64,quartzpro64", "rockchip,rk3588";
 
        aliases {
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       sram-supply = <&vdd_gpu_mem_s0>;
+       status = "okay";
+};
+
 &i2c2 {
        status = "okay";
 
                regulators {
                        vdd_gpu_s0: dcdc-reg1 {
                                regulator-name = "vdd_gpu_s0";
+                               /* regulator coupling requires always-on */
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-enable-ramp-delay = <400>;
                                regulator-min-microvolt = <550000>;
                                regulator-max-microvolt = <950000>;
                                regulator-ramp-delay = <12500>;
+                               regulator-coupled-with = <&vdd_gpu_mem_s0>;
+                               regulator-coupled-max-spread = <10000>;
 
                                regulator-state-mem {
                                        regulator-off-in-suspend;
 
                        vdd_gpu_mem_s0: dcdc-reg5 {
                                regulator-name = "vdd_gpu_mem_s0";
+                               /* regulator coupling requires always-on */
+                               regulator-always-on;
                                regulator-boot-on;
                                regulator-enable-ramp-delay = <400>;
                                regulator-min-microvolt = <675000>;
                                regulator-max-microvolt = <950000>;
                                regulator-ramp-delay = <12500>;
+                               regulator-coupled-with = <&vdd_gpu_s0>;
+                               regulator-coupled-max-spread = <10000>;
 
                                regulator-state-mem {
                                        regulator-off-in-suspend;
index 1fe8b2a0ed75eeb3360fa82ceeb031be8e06e6b7..b8e15b76a8a6cd1029367b681186c849c9660728 100644 (file)
@@ -7,7 +7,7 @@
 #include "rk3588.dtsi"
 
 / {
-       model = "Radxa ROCK 5 Model B";
+       model = "Radxa ROCK 5B";
        compatible = "radxa,rock-5b", "rockchip,rk3588";
 
        aliases {
        cpu-supply = <&vdd_cpu_lit_s0>;
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0m2_xfer>;
        status = "okay";
 };
 
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
        status = "okay";
 };
 
+&usbdp_phy1 {
+       status = "okay";
+};
+
 &usb_host0_ehci {
        status = "okay";
 };
        status = "okay";
 };
 
+&usb_host1_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
+
 &usb_host2_xhci {
        status = "okay";
 };
index d672198c6b64032996a2578156996c72c11939fb..e4b7a0a4444bf9362b2a0c557641753b2b604379 100644 (file)
                vin-supply = <&dc_12v>;
        };
 
+       vcc5v0_otg: vcc5v0-otg-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&otg_vbus_drv>;
+               regulator-name = "vcc5v0_otg";
+               regulator-always-on;
+       };
+
        vcc5v0_usb: vcc5v0-usb-regulator {
                compatible = "regulator-fixed";
                regulator-name = "vcc5v0_usb";
        status = "okay";
 };
 
+&extcon_usb3 {
+       status = "okay";
+};
+
 &gmac0 {
        status = "okay";
 };
                                <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
+
+       usb2 {
+               otg_vbus_drv: otg-vbus-drv {
+                       rockchip,pins =
+                         <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
 };
 
 &sdmmc {
        status = "okay";
 };
 
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       phy-supply = <&vcc5v0_otg>;
+       status = "okay";
+};
+
+&u2phy1 {
+       status = "okay";
+};
+
+&u2phy1_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
 };
 
 &uart2 {
-       pinctrl-0 = <&uart2m2_xfer>;
        status = "okay";
 };
 
 &uart5 {
        rts-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+};
+
+&usbdp_phy0 {
        status = "okay";
 };
 
-/* host0 on Q7_USB_P2, lower usb3 port */
+&usbdp_phy1 {
+       status = "okay";
+};
+
+/* host0 on Q7_USB_P2, upper usb3 port */
 &usb_host0_ehci {
        status = "okay";
 };
 
-/* host0 on Q7_USB_P2, lower usb3 port */
+/* host0 on Q7_USB_P2, upper usb3 port */
 &usb_host0_ohci {
        status = "okay";
 };
 
+/* host0_xhci on Q7_USB_P1, usb3-otg port */
+&usb_host0_xhci {
+       dr_mode = "otg";
+       extcon = <&extcon_usb3>;
+       status = "okay";
+};
+
 /* host1 on Q7_USB_P3, usb2 port */
 &usb_host1_ehci {
        status = "okay";
        status = "okay";
 };
 
-/* host2 on Q7_USB_P2, lower usb3 port */
+/* host1_xhci on Q7_USB_P0, lower usb3 port */
+&usb_host1_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
+
+/* host2 on Q7_USB_P2, upper usb3 port */
 &usb_host2_xhci {
        status = "okay";
 };
index 1eb2543a5fde6bab7d9b525ed57c07217f54afc8..aebe1fedd2d81b30a68f9cedd80ba2f329860b7f 100644 (file)
                reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_HIGH>;
        };
 
+       extcon_usb3: extcon-usb3 {
+               compatible = "linux,extcon-usb-gpio";
+               id-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb3_id>;
+               status = "disabled";
+       };
+
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
@@ -46,7 +54,7 @@
        pcie_refclk_gen: pcie-refclk-gen-clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
-               clock-frequency = <1000000000>;
+               clock-frequency = <100000000>;
        };
 
        pcie_refclk: pcie-refclk-clock {
        snps,reset-delays-us = <0 10000 100000>;
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c1 {
        pinctrl-0 = <&i2c1m0_xfer>;
 };
                        rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
+
+       usb3 {
+               usb3_id: usb3-id {
+                       rockchip,pins =
+                         <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
 };
 
 &saradc {
                vcca-supply = <&vcc5v0_sys>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
        status = "okay";
 };
 
+/* Routed to UART0 on the Q7 connector */
+&uart2 {
+       pinctrl-0 = <&uart2m2_xfer>;
+};
+
 /* Mule-ATtiny UPDI */
 &uart4 {
        pinctrl-0 = <&uart4m2_xfer>;
index dc08da518a76d13cc4841c44a8844a348785f023..6b9206ce4a03bf99831081fb81a936c4d5d56eeb 100644 (file)
                #gpio-cells = <2>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
index 5519c1430cb7a92df91765243ac29fc7e1a2407b..5984016b5f96de290d9840f81b5f55061e3448d0 100644 (file)
@@ -7,6 +7,26 @@
 #include "rk3588-pinctrl.dtsi"
 
 / {
+       usb_host1_xhci: usb@fc400000 {
+               compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+               reg = <0x0 0xfc400000 0x0 0x400000>;
+               interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
+                        <&cru ACLK_USB3OTG1>;
+               clock-names = "ref_clk", "suspend_clk", "bus_clk";
+               dr_mode = "otg";
+               phys = <&u2phy1_otg>, <&usbdp_phy1 PHY_TYPE_USB3>;
+               phy-names = "usb2-phy", "usb3-phy";
+               phy_type = "utmi_wide";
+               power-domains = <&power RK3588_PD_USB>;
+               resets = <&cru SRST_A_USB3OTG1>;
+               snps,dis_enblslpm_quirk;
+               snps,dis-u2-freeclk-exists-quirk;
+               snps,dis-del-phy-power-chg-quirk;
+               snps,dis-tx-ipgap-linecheck-quirk;
+               status = "disabled";
+       };
+
        pcie30_phy_grf: syscon@fd5b8000 {
                compatible = "rockchip,rk3588-pcie3-phy-grf", "syscon";
                reg = <0x0 0xfd5b8000 0x0 0x10000>;
                reg = <0x0 0xfd5c0000 0x0 0x100>;
        };
 
+       usbdpphy1_grf: syscon@fd5cc000 {
+               compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+               reg = <0x0 0xfd5cc000 0x0 0x4000>;
+       };
+
+       usb2phy1_grf: syscon@fd5d4000 {
+               compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xfd5d4000 0x0 0x4000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               u2phy1: usb2phy@4000 {
+                       compatible = "rockchip,rk3588-usb2phy";
+                       reg = <0x4000 0x10>;
+                       #clock-cells = <0>;
+                       clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+                       clock-names = "phyclk";
+                       clock-output-names = "usb480m_phy1";
+                       interrupts = <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH 0>;
+                       resets = <&cru SRST_OTGPHY_U3_1>, <&cru SRST_P_USB2PHY_U3_1_GRF0>;
+                       reset-names = "phy", "apb";
+                       status = "disabled";
+
+                       u2phy1_otg: otg-port {
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+       };
+
        i2s8_8ch: i2s@fddc8000 {
                compatible = "rockchip,rk3588-i2s-tdm";
                reg = <0x0 0xfddc8000 0x0 0x1000>;
                };
        };
 
+       usbdp_phy1: phy@fed90000 {
+               compatible = "rockchip,rk3588-usbdp-phy";
+               reg = <0x0 0xfed90000 0x0 0x10000>;
+               #phy-cells = <1>;
+               clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+                        <&cru CLK_USBDP_PHY1_IMMORTAL>,
+                        <&cru PCLK_USBDPPHY1>,
+                        <&u2phy1>;
+               clock-names = "refclk", "immortal", "pclk", "utmi";
+               resets = <&cru SRST_USBDP_COMBO_PHY1_INIT>,
+                        <&cru SRST_USBDP_COMBO_PHY1_CMN>,
+                        <&cru SRST_USBDP_COMBO_PHY1_LANE>,
+                        <&cru SRST_USBDP_COMBO_PHY1_PCS>,
+                        <&cru SRST_P_USBDPPHY1>;
+               reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+               rockchip,u2phy-grf = <&usb2phy1_grf>;
+               rockchip,usb-grf = <&usb_grf>;
+               rockchip,usbdpphy-grf = <&usbdpphy1_grf>;
+               rockchip,vo-grf = <&vo0_grf>;
+               status = "disabled";
+       };
+
        combphy1_ps: phy@fee10000 {
                compatible = "rockchip,rk3588-naneng-combphy";
                reg = <0x0 0xfee10000 0x0 0x100>;
index e037bf9db75af0402dccd26b82b50922823fe9f7..3b2ec1d0c542122ebb680f261c0cd4e9b8093979 100644 (file)
        cpu-supply = <&vdd_cpu_big1_s0>;
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-0 = <&i2c0m2_xfer>;
        status = "okay";
                vcca-supply = <&vcc5v0_sys>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
index ce8119cbb82485ac39c3b15dfae234f1666ec3c9..d8c50fdcca3b57e50d70325e1d7a7efad2e314bd 100644 (file)
                pinctrl-names = "default";
                vbus-supply = <&vbus5v0_typec>;
 
-               connector {
+               usb_con: connector {
                        compatible = "usb-c-connector";
                        data-role = "dual";
                        label = "USB-C";
                        source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
                        sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
                        op-sink-microwatt = <1000000>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       usbc0_orien_sw: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_orientation_switch>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       usbc0_role_sw: endpoint {
+                                               remote-endpoint = <&dwc3_0_role_switch>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       dp_altmode_mux: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+                                       };
+                               };
+                       };
                };
        };
 
                vcca-supply = <&vcc5v0_sys>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
        status = "okay";
 };
 
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
        status = "okay";
 };
 
+&usb_host0_xhci {
+       usb-role-switch;
+       status = "okay";
+
+       port {
+               dwc3_0_role_switch: endpoint {
+                       remote-endpoint = <&usbc0_role_sw>;
+               };
+       };
+};
+
 &usb_host1_ehci {
        status = "okay";
 };
 &usb_host2_xhci {
        status = "okay";
 };
+
+&usbdp_phy0 {
+       orientation-switch;
+       mode-switch;
+       sbu1-dc-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
+       sbu2-dc-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
+       rockchip,dp-lane-mux = <2 3>;
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usbdp_phy0_orientation_switch: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&usbc0_orien_sw>;
+               };
+
+               usbdp_phy0_dp_altmode_mux: endpoint@1 {
+                       reg = <1>;
+                       remote-endpoint = <&dp_altmode_mux>;
+               };
+       };
+};
index f53e993c785edbf25a31e0d30bf945ebe78d6934..dbddfc3bb4641725568784447d5eacf7d8612136 100644 (file)
@@ -3,7 +3,9 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/leds/common.h>
 #include "rk3588s.dtsi"
 
 / {
 
        aliases {
                mmc0 = &sdhci;
+               mmc1 = &sdmmc;
        };
 
        chosen {
                stdout-path = "serial2:1500000n8";
        };
+
+       adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 1>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+               poll-interval = <100>;
+
+               button-function {
+                       label = "Function";
+                       linux,code = <KEY_FN>;
+                       press-threshold-microvolt = <17000>;
+               };
+       };
+
+       ir-receiver {
+               compatible = "gpio-ir-receiver";
+               gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&ir_receiver_pin>;
+       };
+
+       leds {
+               compatible = "pwm-leds";
+
+               red_led: led-0 {
+                       label = "red_led";
+                       color = <LED_COLOR_ID_RED>;
+                       default-state = "off";
+                       function = LED_FUNCTION_INDICATOR;
+                       linux,default-trigger = "none";
+                       max-brightness = <255>;
+                       pwms = <&pwm11 0 25000 0>;
+               };
+
+               green_led: led-1 {
+                       label = "green_led";
+                       color = <LED_COLOR_ID_GREEN>;
+                       default-state = "on";
+                       function = LED_FUNCTION_POWER;
+                       linux,default-trigger = "default-on";
+                       max-brightness = <255>;
+                       pwms = <&pwm14 0 25000 0>;
+               };
+
+               blue_led: led-2 {
+                       label = "blue_led";
+                       color = <LED_COLOR_ID_BLUE>;
+                       default-state = "off";
+                       function = LED_FUNCTION_INDICATOR;
+                       linux,default-trigger = "none";
+                       max-brightness = <255>;
+                       pwms = <&pwm15 0 25000 0>;
+               };
+       };
+
+       vcc3v3_pcie_wl: vcc3v3-pcie-wl-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie2_2_vcc3v3_en>;
+               regulator-name = "vcc3v3_pcie_wl";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <5000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_host";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               enable-active-high;
+               gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       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>;
+       };
+
+       vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_1v1_nldo_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1100000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vdd_3v3_sd: vdd-3v3-sd-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_3v3_sd";
+               gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               enable-active-high;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_3v3_s3>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vdd_sd_en>;
+       };
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+       cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&combphy0_ps {
+       status = "okay";
+};
+
+&combphy2_psu {
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c0m2_xfer>;
+       status = "okay";
+
+       vdd_cpu_big0_s0: regulator@42 {
+               compatible = "rockchip,rk8602";
+               reg = <0x42>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big0_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_cpu_big1_s0: regulator@43 {
+               compatible = "rockchip,rk8603", "rockchip,rk8602";
+               reg = <0x43>;
+               fcs,suspend-voltage-selector = <1>;
+               regulator-name = "vdd_cpu_big1_s0";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <550000>;
+               regulator-max-microvolt = <1050000>;
+               regulator-ramp-delay = <2300>;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+
+       hym8563: rtc@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+               clock-output-names = "hym8563";
+               wakeup-source;
+       };
+};
+
+&pinctrl {
+       vdd_sd {
+               vdd_sd_en: vdd-sd-en {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       pcie2 {
+               pcie2_2_rst: pcie2-2-rst {
+                       rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie2_2_vcc3v3_en: pcie2-2-vcc-en {
+                       rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       ir-receiver {
+               ir_receiver_pin: ir-receiver-pin {
+                       rockchip,pins = <1  RK_PA7  RK_FUNC_GPIO  &pcfg_pull_none>;
+               };
+       };
+
+       wireless-bluetooth {
+               bt_reset_pin: bt-reset-pin {
+                       rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_wake_pin: bt-wake-pin {
+                       rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               bt_wake_host_irq: bt-wake-host-irq {
+                       rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+};
+
+&pcie2x1l2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie2_2_rst>;
+       reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+       vpcie3v3-supply = <&vcc3v3_pcie_wl>;
+       status = "okay";
+};
+
+&pwm11 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm11m1_pins>;
+       status = "okay";
+};
+
+&pwm14 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm14m1_pins>;
+       status = "okay";
+};
+
+&pwm15 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pwm15m1_pins>;
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&avcc_1v8_s0>;
+       status = "okay";
 };
 
 &sdhci {
        status = "okay";
 };
 
+&sdmmc {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       disable-wp;
+       no-mmc;
+       no-sdio;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vdd_3v3_sd>;
+       vqmmc-supply = <&vccio_sd_s0>;
+       status = "okay";
+};
+
+&sfc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&fspim2_pins>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-max-frequency = <100000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+       };
+};
+
+&spi2 {
+       assigned-clocks = <&cru CLK_SPI2>;
+       assigned-clock-rates = <200000000>;
+       num-cs = <1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+       status = "okay";
+
+       pmic@0 {
+               compatible = "rockchip,rk806";
+               reg = <0x0>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+                           <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+               spi-max-frequency = <1000000>;
+               system-power-controller;
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc5-supply = <&vcc5v0_sys>;
+               vcc6-supply = <&vcc5v0_sys>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc5v0_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+               vcc10-supply = <&vcc5v0_sys>;
+               vcc11-supply = <&vcc_2v0_pldo_s3>;
+               vcc12-supply = <&vcc5v0_sys>;
+               vcc13-supply = <&vcc_1v1_nldo_s3>;
+               vcc14-supply = <&vcc_1v1_nldo_s3>;
+               vcca-supply = <&vcc5v0_sys>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               rk806_dvs1_null: dvs1-null-pins {
+                       pins = "gpio_pwrctrl1";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs2_null: dvs2-null-pins {
+                       pins = "gpio_pwrctrl2";
+                       function = "pin_fun0";
+               };
+
+               rk806_dvs3_null: dvs3-null-pins {
+                       pins = "gpio_pwrctrl3";
+                       function = "pin_fun0";
+               };
+
+               regulators {
+                       vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+                               regulator-boot-on;
+                               regulator-enable-ramp-delay = <400>;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-name = "vdd_gpu_s0";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-name = "vdd_cpu_lit_s0";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_log_s0: dcdc-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_log_s0";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <550000>;
+                               regulator-max-microvolt = <950000>;
+                               regulator-name = "vdd_vdenc_s0";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_ddr_s0: dcdc-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <675000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-name = "vdd_ddr_s0";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       vdd2_ddr_s3: dcdc-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vdd2_ddr_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_2v0_pldo_s3: dcdc-reg7 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <2000000>;
+                               regulator-max-microvolt = <2000000>;
+                               regulator-name = "vdd_2v0_pldo_s3";
+                               regulator-ramp-delay = <12500>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <2000000>;
+                               };
+                       };
+
+                       vcc_3v3_s3: dcdc-reg8 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-name = "vcc_3v3_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vddq_ddr_s0: dcdc-reg9 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-name = "vddq_ddr_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s3: dcdc-reg10 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avcc_1v8_s0: pldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "avcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8_s0: pldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "vcc_1v8_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       avdd_1v2_s0: pldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-name = "avdd_1v2_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v3_s0: pldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vcc_3v3_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vccio_sd_s0: pldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-name = "vccio_sd_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       pldo6_s3: pldo-reg6 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-name = "pldo6_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vdd_0v75_s3: nldo-reg1 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s3";
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <750000>;
+                               };
+                       };
+
+                       vdd_ddr_pll_s0: nldo-reg2 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_ddr_pll_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <850000>;
+                               };
+                       };
+
+                       avdd_0v75_s0: nldo-reg3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "avdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v85_s0: nldo-reg4 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <850000>;
+                               regulator-name = "vdd_0v85_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_0v75_s0: nldo-reg5 {
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-name = "vdd_0v75_s0";
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&tsadc {
+       status = "okay";
+};
+
 &uart2 {
        pinctrl-0 = <&uart2m0_xfer>;
        status = "okay";
 };
+
+&uart9 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart9m2_xfer &uart9m2_ctsn>;
+       status = "okay";
+};
+
+&u2phy2 {
+       status = "okay";
+};
+
+&u2phy2_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&u2phy3 {
+       status = "okay";
+};
+
+&u2phy3_host {
+       phy-supply = <&vcc5v0_host>;
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usb_host2_xhci {
+       status = "okay";
+};
index 25de4362af386747983e810d650d74c2afaa67fd..feea6b20a6bf54ffa60f819a91138eaf9288d1f0 100644 (file)
@@ -6,6 +6,7 @@
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
 #include "rk3588s.dtsi"
 
 / {
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu_s0>;
+       status = "okay";
+};
+
 &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0m2_xfer>;
        pinctrl-0 = <&i2c6m3_xfer>;
        status = "okay";
 
+       usbc0: usb-typec@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usbc0_int>;
+               vbus-supply = <&vbus_typec>;
+               status = "okay";
+
+               usb_con: connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       data-role = "dual";
+                       op-sink-microwatt = <1000000>;
+                       power-role = "dual";
+                       sink-pdos =
+                               <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
+                       source-pdos =
+                               <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+                       try-power-role = "source";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       usbc0_hs: endpoint {
+                                               remote-endpoint = <&usb_host0_xhci_drd_sw>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       usbc0_ss: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_typec_ss>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       usbc0_sbu: endpoint {
+                                               remote-endpoint = <&usbdp_phy0_typec_sbu>;
+                                       };
+                               };
+                       };
+               };
+       };
+
        hym8563: rtc@51 {
                compatible = "haoyu,hym8563";
                reg = <0x51>;
                #gpio-cells = <2>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
        status = "okay";
 };
 
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
        status = "okay";
 };
 
+&usbdp_phy0 {
+       mode-switch;
+       orientation-switch;
+       sbu1-dc-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+       sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               usbdp_phy0_typec_ss: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&usbc0_ss>;
+               };
+
+               usbdp_phy0_typec_sbu: endpoint@1 {
+                       reg = <1>;
+                       remote-endpoint = <&usbc0_sbu>;
+               };
+       };
+};
+
 &usb_host0_ehci {
        status = "okay";
 };
        status = "okay";
 };
 
+&usb_host0_xhci {
+       dr_mode = "otg";
+       usb-role-switch;
+       status = "okay";
+
+       port {
+               usb_host0_xhci_drd_sw: endpoint {
+                       remote-endpoint = <&usbc0_hs>;
+               };
+       };
+};
+
 &usb_host1_ehci {
        status = "okay";
 };
index 00afb90d4eb10bab9db61591c9f5cb167c37ec93..8e2a07612d1735284072033d533acc322a61e637 100644 (file)
@@ -8,7 +8,7 @@
 #include "rk3588s.dtsi"
 
 / {
-       model = "Radxa ROCK 5 Model A";
+       model = "Radxa ROCK 5A";
        compatible = "radxa,rock-5a", "rockchip,rk3588s";
 
        aliases {
                #gpio-cells = <2>;
 
                rk806_dvs1_null: dvs1-null-pins {
-                       pins = "gpio_pwrctrl2";
+                       pins = "gpio_pwrctrl1";
                        function = "pin_fun0";
                };
 
        };
 };
 
+&u2phy0 {
+       status = "okay";
+};
+
+&u2phy0_otg {
+       status = "okay";
+};
+
 &u2phy2 {
        status = "okay";
 };
        status = "okay";
 };
 
+&usbdp_phy0 {
+       status = "okay";
+       rockchip,dp-lane-mux = <2 3>;
+};
+
 &usb_host0_ehci {
        status = "okay";
        pinctrl-names = "default";
        status = "okay";
 };
 
+&usb_host0_xhci {
+       dr_mode = "host";
+       status = "okay";
+};
+
 &usb_host1_ehci {
        status = "okay";
 };
index 87b83c87bd55155623342fe002ad67cbe104b83c..6ac5ac8b48abbd0fe9b0778501a3b60abc507a71 100644 (file)
                };
        };
 
+       display_subsystem: display-subsystem {
+               compatible = "rockchip,display-subsystem";
+               ports = <&vop_out>;
+       };
+
        firmware {
                optee: optee {
                        compatible = "linaro,optee-tz";
                #clock-cells = <0>;
        };
 
-       display_subsystem: display-subsystem {
-               compatible = "rockchip,display-subsystem";
-               ports = <&vop_out>;
-       };
-
        timer {
                compatible = "arm,armv8-timer";
                interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
                };
        };
 
+       gpu: gpu@fb000000 {
+               compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf";
+               reg = <0x0 0xfb000000 0x0 0x200000>;
+               #cooling-cells = <2>;
+               assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+               assigned-clock-rates = <200000000>;
+               clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>,
+                        <&cru CLK_GPU_STACKS>;
+               clock-names = "core", "coregroup", "stacks";
+               dynamic-power-coefficient = <2982>;
+               interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupt-names = "job", "mmu", "gpu";
+               operating-points-v2 = <&gpu_opp_table>;
+               power-domains = <&power RK3588_PD_GPU>;
+               status = "disabled";
+
+               gpu_opp_table: opp-table {
+                       compatible = "operating-points-v2";
+
+                       opp-300000000 {
+                               opp-hz = /bits/ 64 <300000000>;
+                               opp-microvolt = <675000 675000 850000>;
+                       };
+                       opp-400000000 {
+                               opp-hz = /bits/ 64 <400000000>;
+                               opp-microvolt = <675000 675000 850000>;
+                       };
+                       opp-500000000 {
+                               opp-hz = /bits/ 64 <500000000>;
+                               opp-microvolt = <675000 675000 850000>;
+                       };
+                       opp-600000000 {
+                               opp-hz = /bits/ 64 <600000000>;
+                               opp-microvolt = <675000 675000 850000>;
+                       };
+                       opp-700000000 {
+                               opp-hz = /bits/ 64 <700000000>;
+                               opp-microvolt = <700000 700000 850000>;
+                       };
+                       opp-800000000 {
+                               opp-hz = /bits/ 64 <800000000>;
+                               opp-microvolt = <750000 750000 850000>;
+                       };
+                       opp-900000000 {
+                               opp-hz = /bits/ 64 <900000000>;
+                               opp-microvolt = <800000 800000 850000>;
+                       };
+                       opp-1000000000 {
+                               opp-hz = /bits/ 64 <1000000000>;
+                               opp-microvolt = <850000 850000 850000>;
+                       };
+               };
+       };
+
+       usb_host0_xhci: usb@fc000000 {
+               compatible = "rockchip,rk3588-dwc3", "snps,dwc3";
+               reg = <0x0 0xfc000000 0x0 0x400000>;
+               interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
+                        <&cru ACLK_USB3OTG0>;
+               clock-names = "ref_clk", "suspend_clk", "bus_clk";
+               dr_mode = "otg";
+               phys = <&u2phy0_otg>, <&usbdp_phy0 PHY_TYPE_USB3>;
+               phy-names = "usb2-phy", "usb3-phy";
+               phy_type = "utmi_wide";
+               power-domains = <&power RK3588_PD_USB>;
+               resets = <&cru SRST_A_USB3OTG0>;
+               snps,dis_enblslpm_quirk;
+               snps,dis-u1-entry-quirk;
+               snps,dis-u2-entry-quirk;
+               snps,dis-u2-freeclk-exists-quirk;
+               snps,dis-del-phy-power-chg-quirk;
+               snps,dis-tx-ipgap-linecheck-quirk;
+               status = "disabled";
+       };
+
        usb_host0_ehci: usb@fc800000 {
                compatible = "rockchip,rk3588-ehci", "generic-ehci";
                reg = <0x0 0xfc800000 0x0 0x40000>;
                status = "disabled";
        };
 
+       mmu600_pcie: iommu@fc900000 {
+               compatible = "arm,smmu-v3";
+               reg = <0x0 0xfc900000 0x0 0x200000>;
+               interrupts = <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
+       mmu600_php: iommu@fcb00000 {
+               compatible = "arm,smmu-v3";
+               reg = <0x0 0xfcb00000 0x0 0x200000>;
+               interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
+               #iommu-cells = <1>;
+               status = "disabled";
+       };
+
        pmu1grf: syscon@fd58a000 {
                compatible = "rockchip,rk3588-pmugrf", "syscon", "simple-mfd";
                reg = <0x0 0xfd58a000 0x0 0x10000>;
                reg = <0x0 0xfd5a4000 0x0 0x2000>;
        };
 
+       vo0_grf: syscon@fd5a6000 {
+               compatible = "rockchip,rk3588-vo-grf", "syscon";
+               reg = <0x0 0xfd5a6000 0x0 0x2000>;
+               clocks = <&cru PCLK_VO0GRF>;
+       };
+
        vo1_grf: syscon@fd5a8000 {
                compatible = "rockchip,rk3588-vo-grf", "syscon";
                reg = <0x0 0xfd5a8000 0x0 0x100>;
                clocks = <&cru PCLK_VO1GRF>;
        };
 
+       usb_grf: syscon@fd5ac000 {
+               compatible = "rockchip,rk3588-usb-grf", "syscon";
+               reg = <0x0 0xfd5ac000 0x0 0x4000>;
+       };
+
        php_grf: syscon@fd5b0000 {
                compatible = "rockchip,rk3588-php-grf", "syscon";
                reg = <0x0 0xfd5b0000 0x0 0x1000>;
                reg = <0x0 0xfd5c4000 0x0 0x100>;
        };
 
+       usbdpphy0_grf: syscon@fd5c8000 {
+               compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+               reg = <0x0 0xfd5c8000 0x0 0x4000>;
+       };
+
+       usb2phy0_grf: syscon@fd5d0000 {
+               compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
+               reg = <0x0 0xfd5d0000 0x0 0x4000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               u2phy0: usb2phy@0 {
+                       compatible = "rockchip,rk3588-usb2phy";
+                       reg = <0x0 0x10>;
+                       #clock-cells = <0>;
+                       clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
+                       clock-names = "phyclk";
+                       clock-output-names = "usb480m_phy0";
+                       interrupts = <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH 0>;
+                       resets = <&cru SRST_OTGPHY_U3_0>, <&cru SRST_P_USB2PHY_U3_0_GRF0>;
+                       reset-names = "phy", "apb";
+                       status = "disabled";
+
+                       u2phy0_otg: otg-port {
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+               };
+       };
+
        usb2phy2_grf: syscon@fd5d8000 {
                compatible = "rockchip,rk3588-usb2phy-grf", "syscon", "simple-mfd";
                reg = <0x0 0xfd5d8000 0x0 0x4000>;
                #address-cells = <1>;
                #size-cells = <1>;
 
-               u2phy2: usb2-phy@8000 {
+               u2phy2: usb2phy@8000 {
                        compatible = "rockchip,rk3588-usb2phy";
                        reg = <0x8000 0x10>;
-                       interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
-                       resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
-                       reset-names = "phy", "apb";
+                       #clock-cells = <0>;
                        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
                        clock-names = "phyclk";
                        clock-output-names = "usb480m_phy2";
-                       #clock-cells = <0>;
+                       interrupts = <GIC_SPI 391 IRQ_TYPE_LEVEL_HIGH 0>;
+                       resets = <&cru SRST_OTGPHY_U2_0>, <&cru SRST_P_USB2PHY_U2_0_GRF0>;
+                       reset-names = "phy", "apb";
                        status = "disabled";
 
                        u2phy2_host: host-port {
                #address-cells = <1>;
                #size-cells = <1>;
 
-               u2phy3: usb2-phy@c000 {
+               u2phy3: usb2phy@c000 {
                        compatible = "rockchip,rk3588-usb2phy";
                        reg = <0xc000 0x10>;
-                       interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
-                       resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
-                       reset-names = "phy", "apb";
+                       #clock-cells = <0>;
                        clocks = <&cru CLK_USB2PHY_HDPTXRXPHY_REF>;
                        clock-names = "phyclk";
                        clock-output-names = "usb480m_phy3";
-                       #clock-cells = <0>;
+                       interrupts = <GIC_SPI 392 IRQ_TYPE_LEVEL_HIGH 0>;
+                       resets = <&cru SRST_OTGPHY_U2_1>, <&cru SRST_P_USB2PHY_U2_1_GRF0>;
+                       reset-names = "phy", "apb";
                        status = "disabled";
 
                        u2phy3_host: host-port {
                status = "disabled";
        };
 
-       vop: vop@fdd90000 {
-               compatible = "rockchip,rk3588-vop";
-               reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
-               reg-names = "vop", "gamma-lut";
-               interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
-               clocks = <&cru ACLK_VOP>,
-                        <&cru HCLK_VOP>,
-                        <&cru DCLK_VOP0>,
-                        <&cru DCLK_VOP1>,
-                        <&cru DCLK_VOP2>,
-                        <&cru DCLK_VOP3>,
-                        <&cru PCLK_VOP_ROOT>;
-               clock-names = "aclk",
-                             "hclk",
-                             "dclk_vp0",
-                             "dclk_vp1",
-                             "dclk_vp2",
-                             "dclk_vp3",
-                             "pclk_vop";
-               iommus = <&vop_mmu>;
-               power-domains = <&power RK3588_PD_VOP>;
-               rockchip,grf = <&sys_grf>;
-               rockchip,vop-grf = <&vop_grf>;
-               rockchip,vo1-grf = <&vo1_grf>;
-               rockchip,pmu = <&pmu>;
-               status = "disabled";
-
-               vop_out: ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       vp0: port@0 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <0>;
-                       };
-
-                       vp1: port@1 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <1>;
-                       };
-
-                       vp2: port@2 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <2>;
-                       };
-
-                       vp3: port@3 {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               reg = <3>;
-                       };
-               };
-       };
-
-       vop_mmu: iommu@fdd97e00 {
-               compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
-               reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
-               interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
-               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
-               clock-names = "aclk", "iface";
-               #iommu-cells = <0>;
-               power-domains = <&power RK3588_PD_VOP>;
-               status = "disabled";
-       };
-
        uart0: serial@fd890000 {
                compatible = "rockchip,rk3588-uart", "snps,dw-apb-uart";
                reg = <0x0 0xfd890000 0x0 0x100>;
                };
        };
 
+       av1d: video-codec@fdc70000 {
+               compatible = "rockchip,rk3588-av1-vpu";
+               reg = <0x0 0xfdc70000 0x0 0x800>;
+               interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+               interrupt-names = "vdpu";
+               assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+               assigned-clock-rates = <400000000>, <400000000>;
+               clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+               clock-names = "aclk", "hclk";
+               power-domains = <&power RK3588_PD_AV1>;
+               resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+       };
+
+       vop: vop@fdd90000 {
+               compatible = "rockchip,rk3588-vop";
+               reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;
+               reg-names = "vop", "gamma-lut";
+               interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP>,
+                        <&cru HCLK_VOP>,
+                        <&cru DCLK_VOP0>,
+                        <&cru DCLK_VOP1>,
+                        <&cru DCLK_VOP2>,
+                        <&cru DCLK_VOP3>,
+                        <&cru PCLK_VOP_ROOT>;
+               clock-names = "aclk",
+                             "hclk",
+                             "dclk_vp0",
+                             "dclk_vp1",
+                             "dclk_vp2",
+                             "dclk_vp3",
+                             "pclk_vop";
+               iommus = <&vop_mmu>;
+               power-domains = <&power RK3588_PD_VOP>;
+               rockchip,grf = <&sys_grf>;
+               rockchip,vop-grf = <&vop_grf>;
+               rockchip,vo1-grf = <&vo1_grf>;
+               rockchip,pmu = <&pmu>;
+               status = "disabled";
+
+               vop_out: ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       vp0: port@0 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0>;
+                       };
+
+                       vp1: port@1 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <1>;
+                       };
+
+                       vp2: port@2 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <2>;
+                       };
+
+                       vp3: port@3 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <3>;
+                       };
+               };
+       };
+
+       vop_mmu: iommu@fdd97e00 {
+               compatible = "rockchip,rk3588-iommu", "rockchip,rk3568-iommu";
+               reg = <0x0 0xfdd97e00 0x0 0x100>, <0x0 0xfdd97f00 0x0 0x100>;
+               interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+               clock-names = "aclk", "iface";
+               #iommu-cells = <0>;
+               power-domains = <&power RK3588_PD_VOP>;
+               status = "disabled";
+       };
+
        i2s4_8ch: i2s@fddc0000 {
                compatible = "rockchip,rk3588-i2s-tdm";
                reg = <0x0 0xfddc0000 0x0 0x1000>;
                reg = <0x0 0xfdf82200 0x0 0x20>;
        };
 
+       dfi: dfi@fe060000 {
+               reg = <0x00 0xfe060000 0x00 0x10000>;
+               compatible = "rockchip,rk3588-dfi";
+               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
+                            <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
+               rockchip,pmu = <&pmu1grf>;
+       };
+
        pcie2x1l1: pcie@fe180000 {
                compatible = "rockchip,rk3588-pcie", "rockchip,rk3568-pcie";
                bus-range = <0x30 0x3f>;
                };
        };
 
-       dfi: dfi@fe060000 {
-               reg = <0x00 0xfe060000 0x00 0x10000>;
-               compatible = "rockchip,rk3588-dfi";
-               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>,
-                            <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>,
-                            <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>,
-                            <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>;
-               rockchip,pmu = <&pmu1grf>;
-       };
-
        gmac1: ethernet@fe1c0000 {
                compatible = "rockchip,rk3588-gmac", "snps,dwmac-4.20a";
                reg = <0x0 0xfe1c0000 0x0 0x10000>;
                status = "disabled";
        };
 
+       usbdp_phy0: phy@fed80000 {
+               compatible = "rockchip,rk3588-usbdp-phy";
+               reg = <0x0 0xfed80000 0x0 0x10000>;
+               #phy-cells = <1>;
+               clocks = <&cru CLK_USBDPPHY_MIPIDCPPHY_REF>,
+                        <&cru CLK_USBDP_PHY0_IMMORTAL>,
+                        <&cru PCLK_USBDPPHY0>,
+                        <&u2phy0>;
+               clock-names = "refclk", "immortal", "pclk", "utmi";
+               resets = <&cru SRST_USBDP_COMBO_PHY0_INIT>,
+                        <&cru SRST_USBDP_COMBO_PHY0_CMN>,
+                        <&cru SRST_USBDP_COMBO_PHY0_LANE>,
+                        <&cru SRST_USBDP_COMBO_PHY0_PCS>,
+                        <&cru SRST_P_USBDPPHY0>;
+               reset-names = "init", "cmn", "lane", "pcs_apb", "pma_apb";
+               rockchip,u2phy-grf = <&usb2phy0_grf>;
+               rockchip,usb-grf = <&usb_grf>;
+               rockchip,usbdpphy-grf = <&usbdpphy0_grf>;
+               rockchip,vo-grf = <&vo0_grf>;
+               status = "disabled";
+       };
+
        combphy0_ps: phy@fee00000 {
                compatible = "rockchip,rk3588-naneng-combphy";
                reg = <0x0 0xfee00000 0x0 0x100>;
                        #interrupt-cells = <2>;
                };
        };
-
-       av1d: video-codec@fdc70000 {
-               compatible = "rockchip,rk3588-av1-vpu";
-               reg = <0x0 0xfdc70000 0x0 0x800>;
-               interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
-               interrupt-names = "vdpu";
-               assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
-               assigned-clock-rates = <400000000>, <400000000>;
-               clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
-               clock-names = "aclk", "hclk";
-               power-domains = <&power RK3588_PD_AV1>;
-               resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
-       };
 };
 
 #include "rk3588s-pinctrl.dtsi"
index da44a15a8adf3e886b17575a9543e6caa6a7f2a5..a251c4343548f47772e06a2a6f59851b7ac938f4 100644 (file)
 &i2c0 {
        status = "okay";
 
-       tas5707a@1d {
+       audio-codec@1d {
                compatible = "ti,tas5711";
                reg = <0x1d>;
                reset-gpios = <&gpio UNIPHIER_GPIO_PORT(23, 4) GPIO_ACTIVE_LOW>;
                PVDD_C-supply = <&amp_vcc_reg>;
                PVDD_D-supply = <&amp_vcc_reg>;
 
-               port@0 {
+               port {
                        tas_speaker: endpoint {
                                dai-format = "i2s";
                                remote-endpoint = <&i2s_hpcmout1>;
index a01579cb3b79cb678f18050007cd145e61539408..79f6db2455c1726f3f0befe8f18063d804d20d94 100644 (file)
 &i2c0 {
        status = "okay";
 
-       tas5707@1b {
+       audio-codec@1b {
                compatible = "ti,tas5711";
                reg = <0x1b>;
                reset-gpios = <&gpio UNIPHIER_GPIO_PORT(0, 0) GPIO_ACTIVE_LOW>;
                PVDD_C-supply = <&amp_vcc_reg>;
                PVDD_D-supply = <&amp_vcc_reg>;
 
-               port@0 {
+               port {
                        tas_speaker: endpoint {
                                dai-format = "i2s";
                                remote-endpoint = <&i2s_hpcmout1>;
index e27eb3ed1d47991be7573d320eb6b5cae2f6a608..31952d361a8a9d0845a0675aa7eff455b0fb30fa 100644 (file)
                };
        };
 
-       idle-states{
+       idle-states {
                entry-method = "psci";
 
                CORE_PD: core_pd {
                };
        };
 
-       gic: interrupt-controller@12001000 {
-               compatible = "arm,gic-400";
-               reg = <0 0x12001000 0 0x1000>,
-                     <0 0x12002000 0 0x2000>,
-                     <0 0x12004000 0 0x2000>,
-                     <0 0x12006000 0 0x2000>;
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8)
-                                       | IRQ_TYPE_LEVEL_HIGH)>;
-       };
-
        psci {
                compatible = "arm,psci-0.2";
                method = "smc";
        };
 
        pmu {
-               compatible = "arm,cortex-a53-pmu", "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
        };
 
        soc {
+               gic: interrupt-controller@12001000 {
+                       compatible = "arm,gic-400";
+                       reg = <0 0x12001000 0 0x1000>,
+                             <0 0x12002000 0 0x2000>,
+                             <0 0x12004000 0 0x2000>,
+                             <0 0x12006000 0 0x2000>;
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8)
+                                               | IRQ_TYPE_LEVEL_HIGH)>;
+               };
+
                pmu_gate: pmu-gate {
                        compatible = "sprd,sc9860-pmu-gate";
                        sprd,syscon = <&pmu_regs>; /* 0x402b0000 */
                        #clock-cells = <1>;
                };
 
-               aon_prediv: aon-prediv {
+               aon_prediv: aon-prediv@402d0000 {
                        compatible = "sprd,sc9860-aon-prediv";
                        reg = <0 0x402d0000 0 0x400>;
                        clocks = <&ext_26m>, <&pll 0>,
                                };
                        };
                };
-
-               gpio-keys {
-                       compatible = "gpio-keys";
-
-                       key-volumedown {
-                               label = "Volume Down Key";
-                               linux,code = <KEY_VOLUMEDOWN>;
-                               gpios = <&eic_debounce 2 GPIO_ACTIVE_LOW>;
-                               debounce-interval = <2>;
-                               wakeup-source;
-                       };
-
-                       key-volumeup {
-                               label = "Volume Up Key";
-                               linux,code = <KEY_VOLUMEUP>;
-                               gpios = <&pmic_eic 10 GPIO_ACTIVE_HIGH>;
-                               debounce-interval = <2>;
-                               wakeup-source;
-                       };
-
-                       key-power {
-                               label = "Power Key";
-                               linux,code = <KEY_POWER>;
-                               gpios = <&pmic_eic 1 GPIO_ACTIVE_HIGH>;
-                               debounce-interval = <2>;
-                               wakeup-source;
-                       };
-               };
        };
 };
index 22d81ace740a0f4ed8159b059282e20dacbf70c1..53e5b77d70b5239f5dda5a055edb680ad66834f3 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a55-pmu";
                interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
index 206a4afdab1cd2a503963108bffaa5589ed8d40d..9b4ee0bdd69f2de8d2a7f126f12490fcddf45075 100644 (file)
@@ -24,7 +24,7 @@
                        #size-cells = <1>;
                        ranges = <0 0 0x20e00000 0x4000>;
 
-                       apahb_gate: apahb-gate {
+                       apahb_gate: apahb-gate@0 {
                                compatible = "sprd,sc9863a-apahb-gate";
                                reg = <0x0 0x1020>;
                                #clock-cells = <1>;
@@ -39,7 +39,7 @@
                        #size-cells = <1>;
                        ranges = <0 0 0x402b0000 0x4000>;
 
-                       pmu_gate: pmu-gate {
+                       pmu_gate: pmu-gate@0 {
                                compatible = "sprd,sc9863a-pmu-gate";
                                reg = <0 0x1200>;
                                clocks = <&ext_26m>;
@@ -56,7 +56,7 @@
                        #size-cells = <1>;
                        ranges = <0 0 0x402e0000 0x4000>;
 
-                       aonapb_gate: aonapb-gate {
+                       aonapb_gate: aonapb-gate@0 {
                                compatible = "sprd,sc9863a-aonapb-gate";
                                reg = <0 0x1100>;
                                #clock-cells = <1>;
@@ -71,7 +71,7 @@
                        #size-cells = <1>;
                        ranges = <0 0 0x40353000 0x3000>;
 
-                       pll: pll {
+                       pll: pll@0 {
                                compatible = "sprd,sc9863a-pll";
                                reg = <0 0x100>;
                                clocks = <&ext_26m>;
@@ -88,7 +88,7 @@
                        #size-cells = <1>;
                        ranges = <0 0 0x40359000 0x3000>;
 
-                       mpll: mpll {
+                       mpll: mpll@0 {
                                compatible = "sprd,sc9863a-mpll";
                                reg = <0 0x100>;
                                #clock-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0 0 0x4035c000 0x3000>;
 
-                       rpll: rpll {
+                       rpll: rpll@0 {
                                compatible = "sprd,sc9863a-rpll";
                                reg = <0 0x100>;
                                clocks = <&ext_26m>;
                        #size-cells = <1>;
                        ranges = <0 0 0x40363000 0x3000>;
 
-                       dpll: dpll {
+                       dpll: dpll@0 {
                                compatible = "sprd,sc9863a-dpll";
                                reg = <0 0x100>;
                                #clock-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0 0 0x60800000 0x3000>;
 
-                       mm_gate: mm-gate {
+                       mm_gate: mm-gate@0 {
                                compatible = "sprd,sc9863a-mm-gate";
                                reg = <0 0x1100>;
                                #clock-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0 0 0x71300000 0x4000>;
 
-                       apapb_gate: apapb-gate {
+                       apapb_gate: apapb-gate@0 {
                                compatible = "sprd,sc9863a-apapb-gate";
                                reg = <0 0x1000>;
                                clocks = <&ext_26m>;
index 6b95fd94cee336ea1be2482a69965766d1f8ac87..1ce3cbbd966844b1138ae3b829335077abb5c4ee 100644 (file)
@@ -24,7 +24,7 @@
                spi0 = &adi_bus;
        };
 
-       memory{
+       memory@80000000 {
                device_type = "memory";
                reg = <0x0 0x80000000 0 0x60000000>,
                      <0x1 0x80000000 0 0x60000000>;
                stdout-path = "serial1:115200n8";
        };
 
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               key-volumedown {
+                       label = "Volume Down Key";
+                       linux,code = <KEY_VOLUMEDOWN>;
+                       gpios = <&eic_debounce 2 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <2>;
+                       wakeup-source;
+               };
+
+               key-volumeup {
+                       label = "Volume Up Key";
+                       linux,code = <KEY_VOLUMEUP>;
+                       gpios = <&pmic_eic 10 GPIO_ACTIVE_HIGH>;
+                       debounce-interval = <2>;
+                       wakeup-source;
+               };
+
+               key-power {
+                       label = "Power Key";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&pmic_eic 1 GPIO_ACTIVE_HIGH>;
+                       debounce-interval = <2>;
+                       wakeup-source;
+               };
+       };
+
        reserved-memory {
                #address-cells = <2>;
                #size-cells = <2>;
index fece49704b5c505fb5f224db80c76afc8615a3ba..7068bfd2f4c34d8be940d08906624a570958c50a 100644 (file)
@@ -64,7 +64,7 @@
                        reg = <0 0x70b00000 0 0x40000>;
                };
 
-               ap-apb {
+               ap-apb@70000000 {
                        compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
index 66791a974f8f29b03f020a01d238eef795bf9522..7a82896dcbf602763c78fd6d087d2df302a60dea 100644 (file)
@@ -6,6 +6,23 @@
 #include <dt-bindings/pinctrl/stm32-pinfunc.h>
 
 &pinctrl {
+       i2c2_pins_a: i2c2-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 5, AF9)>, /* I2C2_SCL */
+                                <STM32_PINMUX('B', 4, AF9)>; /* I2C2_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c2_sleep_pins_a: i2c2-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 5, ANALOG)>, /* I2C2_SCL */
+                                <STM32_PINMUX('B', 4, ANALOG)>; /* I2C2_SDA */
+               };
+       };
+
        sdmmc1_b4_pins_a: sdmmc1-b4-0 {
                pins1 {
                        pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */
                };
        };
 
+       spi3_pins_a: spi3-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 7, AF1)>, /* SPI3_SCK */
+                                <STM32_PINMUX('B', 8, AF1)>; /* SPI3_MOSI */
+                       drive-push-pull;
+                       bias-disable;
+                       slew-rate = <1>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('B', 10, AF1)>; /* SPI3_MISO */
+                       bias-disable;
+               };
+       };
+
+       spi3_sleep_pins_a: spi3-sleep-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 7, ANALOG)>, /* SPI3_SCK */
+                                <STM32_PINMUX('B', 8, ANALOG)>, /* SPI3_MOSI */
+                                <STM32_PINMUX('B', 10, ANALOG)>; /* SPI3_MISO */
+               };
+       };
+
        usart2_pins_a: usart2-0 {
                pins1 {
                        pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */
                };
        };
 };
+
+&pinctrl_z {
+       i2c8_pins_a: i2c8-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 4, AF8)>, /* I2C8_SCL */
+                                <STM32_PINMUX('Z', 3, AF8)>; /* I2C8_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c8_sleep_pins_a: i2c8-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C8_SCL */
+                                <STM32_PINMUX('Z', 3, ANALOG)>; /* I2C8_SDA */
+               };
+       };
+};
+
+&pinctrl_z {
+       spi8_pins_a: spi8-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('Z', 2, AF3)>, /* SPI8_SCK */
+                                <STM32_PINMUX('Z', 0, AF3)>; /* SPI8_MOSI */
+                       drive-push-pull;
+                       bias-disable;
+                       slew-rate = <1>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('Z', 1, AF3)>; /* SPI8_MISO */
+                       bias-disable;
+               };
+       };
+
+       spi8_sleep_pins_a: spi8-sleep-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('Z', 2, ANALOG)>, /* SPI8_SCK */
+                                <STM32_PINMUX('Z', 0, ANALOG)>, /* SPI8_MOSI */
+                                <STM32_PINMUX('Z', 1, ANALOG)>; /* SPI8_MISO */
+               };
+       };
+};
index 5dd4f3580a60feee79fae0946492293ee64b0edc..4b48e4ed2d284cc22e50b9d77e0f264cc1fc8da1 100644 (file)
@@ -3,7 +3,9 @@
  * Copyright (C) STMicroelectronics 2023 - All Rights Reserved
  * Author: Alexandre Torgue <alexandre.torgue@foss.st.com> for STMicroelectronics.
  */
+#include <dt-bindings/clock/st,stm32mp25-rcc.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/st,stm32mp25-rcc.h>
 
 / {
        #address-cells = <2>;
        };
 
        clocks {
-               ck_flexgen_08: ck-flexgen-08 {
+               clk_dsi_txbyte: txbyteclk {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <100000000>;
+                       clock-frequency = <0>;
                };
 
-               ck_flexgen_51: ck-flexgen-51 {
+               clk_rcbsec: clk-rcbsec {
                        #clock-cells = <0>;
                        compatible = "fixed-clock";
-                       clock-frequency = <200000000>;
-               };
-
-               ck_icn_ls_mcu: ck-icn-ls-mcu {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <200000000>;
-               };
-
-               ck_icn_p_vdec: ck-icn-p-vdec {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <200000000>;
-               };
-
-               ck_icn_p_venc: ck-icn-p-venc {
-                       #clock-cells = <0>;
-                       compatible = "fixed-clock";
-                       clock-frequency = <200000000>;
+                       clock-frequency = <64000000>;
                };
        };
 
        timer {
                compatible = "arm,armv8-timer";
                interrupt-parent = <&intc>;
-               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
                always-on;
        };
 
                interrupt-parent = <&intc>;
                ranges = <0x0 0x0 0x0 0x80000000>;
 
-               rifsc: rifsc-bus@42080000 {
-                       compatible = "simple-bus";
+               rifsc: bus@42080000 {
+                       compatible = "st,stm32mp25-rifsc", "simple-bus";
                        reg = <0x42080000 0x1000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
+                       #access-controller-cells = <1>;
                        ranges;
 
+                       spi2: spi@400b0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x400b0000 0x400>;
+                               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI2>;
+                               resets = <&rcc SPI2_R>;
+                               access-controllers = <&rifsc 23>;
+                               status = "disabled";
+                       };
+
+                       spi3: spi@400c0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x400c0000 0x400>;
+                               interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI3>;
+                               resets = <&rcc SPI3_R>;
+                               access-controllers = <&rifsc 24>;
+                               status = "disabled";
+                       };
+
                        usart2: serial@400e0000 {
                                compatible = "st,stm32h7-uart";
                                reg = <0x400e0000 0x400>;
                                interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&ck_flexgen_08>;
+                               clocks = <&rcc CK_KER_USART2>;
+                               access-controllers = <&rifsc 32>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@40120000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40120000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C1>;
+                               resets = <&rcc I2C1_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 41>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@40130000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40130000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C2>;
+                               resets = <&rcc I2C2_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 42>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@40140000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40140000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C3>;
+                               resets = <&rcc I2C3_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 43>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@40150000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40150000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C4>;
+                               resets = <&rcc I2C4_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 44>;
+                               status = "disabled";
+                       };
+
+                       i2c5: i2c@40160000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40160000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C5>;
+                               resets = <&rcc I2C5_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 45>;
+                               status = "disabled";
+                       };
+
+                       i2c6: i2c@40170000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40170000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C6>;
+                               resets = <&rcc I2C6_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 46>;
+                               status = "disabled";
+                       };
+
+                       i2c7: i2c@40180000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x40180000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C7>;
+                               resets = <&rcc I2C7_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 47>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@40230000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x40230000 0x400>;
+                               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI1>;
+                               resets = <&rcc SPI1_R>;
+                               access-controllers = <&rifsc 22>;
+                               status = "disabled";
+                       };
+
+                       spi4: spi@40240000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x40240000 0x400>;
+                               interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI4>;
+                               resets = <&rcc SPI4_R>;
+                               access-controllers = <&rifsc 25>;
+                               status = "disabled";
+                       };
+
+                       spi5: spi@40280000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x40280000 0x400>;
+                               interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI5>;
+                               resets = <&rcc SPI5_R>;
+                               access-controllers = <&rifsc 26>;
+                               status = "disabled";
+                       };
+
+                       spi6: spi@40350000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x40350000 0x400>;
+                               interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI6>;
+                               resets = <&rcc SPI6_R>;
+                               access-controllers = <&rifsc 27>;
+                               status = "disabled";
+                       };
+
+                       spi7: spi@40360000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x40360000 0x400>;
+                               interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI7>;
+                               resets = <&rcc SPI7_R>;
+                               access-controllers = <&rifsc 28>;
+                               status = "disabled";
+                       };
+
+                       spi8: spi@46020000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "st,stm32mp25-spi";
+                               reg = <0x46020000 0x400>;
+                               interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_SPI8>;
+                               resets = <&rcc SPI8_R>;
+                               access-controllers = <&rifsc 29>;
+                               status = "disabled";
+                       };
+
+                       i2c8: i2c@46040000 {
+                               compatible = "st,stm32mp25-i2c";
+                               reg = <0x46040000 0x400>;
+                               interrupt-names = "event";
+                               interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&rcc CK_KER_I2C8>;
+                               resets = <&rcc I2C8_R>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               access-controllers = <&rifsc 48>;
                                status = "disabled";
                        };
 
                                arm,primecell-periphid = <0x00353180>;
                                reg = <0x48220000 0x400>, <0x44230400 0x8>;
                                interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&ck_flexgen_51>;
+                               clocks = <&rcc CK_KER_SDMMC1 >;
                                clock-names = "apb_pclk";
+                               resets = <&rcc SDMMC1_R>;
                                cap-sd-highspeed;
                                cap-mmc-highspeed;
                                max-frequency = <120000000>;
+                               access-controllers = <&rifsc 76>;
                                status = "disabled";
                        };
                };
                        };
                };
 
+               rcc: clock-controller@44200000 {
+                       compatible = "st,stm32mp25-rcc";
+                       reg = <0x44200000 0x10000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       clocks = <&scmi_clk CK_SCMI_HSE>,
+                               <&scmi_clk CK_SCMI_HSI>,
+                               <&scmi_clk CK_SCMI_MSI>,
+                               <&scmi_clk CK_SCMI_LSE>,
+                               <&scmi_clk CK_SCMI_LSI>,
+                               <&scmi_clk CK_SCMI_HSE_DIV2>,
+                               <&scmi_clk CK_SCMI_ICN_HS_MCU>,
+                               <&scmi_clk CK_SCMI_ICN_LS_MCU>,
+                               <&scmi_clk CK_SCMI_ICN_SDMMC>,
+                               <&scmi_clk CK_SCMI_ICN_DDR>,
+                               <&scmi_clk CK_SCMI_ICN_DISPLAY>,
+                               <&scmi_clk CK_SCMI_ICN_HSL>,
+                               <&scmi_clk CK_SCMI_ICN_NIC>,
+                               <&scmi_clk CK_SCMI_ICN_VID>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_07>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_08>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_09>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_10>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_11>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_12>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_13>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_14>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_15>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_16>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_17>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_18>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_19>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_20>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_21>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_22>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_23>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_24>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_25>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_26>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_27>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_28>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_29>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_30>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_31>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_32>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_33>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_34>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_35>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_36>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_37>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_38>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_39>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_40>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_41>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_42>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_43>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_44>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_45>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_46>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_47>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_48>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_49>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_50>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_51>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_52>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_53>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_54>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_55>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_56>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_57>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_58>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_59>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_60>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_61>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_62>,
+                               <&scmi_clk CK_SCMI_FLEXGEN_63>,
+                               <&scmi_clk CK_SCMI_ICN_APB1>,
+                               <&scmi_clk CK_SCMI_ICN_APB2>,
+                               <&scmi_clk CK_SCMI_ICN_APB3>,
+                               <&scmi_clk CK_SCMI_ICN_APB4>,
+                               <&scmi_clk CK_SCMI_ICN_APBDBG>,
+                               <&scmi_clk CK_SCMI_TIMG1>,
+                               <&scmi_clk CK_SCMI_TIMG2>,
+                               <&scmi_clk CK_SCMI_PLL3>,
+                               <&clk_dsi_txbyte>;
+               };
+
                syscfg: syscon@44230000 {
                        compatible = "st,stm32mp25-syscfg", "syscon";
                        reg = <0x44230000 0x10000>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x0 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOA>;
                                st,bank-name = "GPIOA";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x10000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOB>;
                                st,bank-name = "GPIOB";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x20000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOC>;
                                st,bank-name = "GPIOC";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x30000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOD>;
                                st,bank-name = "GPIOD";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x40000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOE>;
                                st,bank-name = "GPIOE";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x50000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOF>;
                                st,bank-name = "GPIOF";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x60000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOG>;
                                st,bank-name = "GPIOG";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x70000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOH>;
                                st,bank-name = "GPIOH";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x80000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOI>;
                                st,bank-name = "GPIOI";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0x90000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOJ>;
                                st,bank-name = "GPIOJ";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0xa0000 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOK>;
                                st,bank-name = "GPIOK";
                                status = "disabled";
                        };
                                interrupt-controller;
                                #interrupt-cells = <2>;
                                reg = <0 0x400>;
-                               clocks = <&ck_icn_ls_mcu>;
+                               clocks = <&scmi_clk CK_SCMI_GPIOZ>;
                                st,bank-name = "GPIOZ";
                                st,bank-ioport = <11>;
                                status = "disabled";
index af48e82efe8a9abeee671b6d31d8460d4987c194..029f8898196167d2300e06c4a4750d1e5e0b0c65 100644 (file)
                             <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-affinity = <&cpu0>, <&cpu1>;
        };
+
+       timer {
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+       };
 };
index 17f197c5b22b1b67973506090ee475ccda5e9998..f689b47c5010033120146cf1954d6624c0270045 100644 (file)
@@ -5,22 +5,21 @@
  */
 #include "stm32mp253.dtsi"
 
-/ {
-       soc@0 {
-               rifsc: rifsc-bus@42080000 {
-                       vdec: vdec@480d0000 {
-                               compatible = "st,stm32mp25-vdec";
-                               reg = <0x480d0000 0x3c8>;
-                               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&ck_icn_p_vdec>;
-                       };
+&rifsc {
+       vdec: vdec@480d0000 {
+               compatible = "st,stm32mp25-vdec";
+               reg = <0x480d0000 0x3c8>;
+               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&rcc CK_BUS_VDEC>;
+               access-controllers = <&rifsc 89>;
 
-                       venc: venc@480e0000 {
-                               compatible = "st,stm32mp25-venc";
-                               reg = <0x480e0000 0x800>;
-                               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&ck_icn_ls_mcu>;
-                       };
-               };
        };
-};
+
+       venc: venc@480e0000 {
+               compatible = "st,stm32mp25-venc";
+               reg = <0x480e0000 0x800>;
+               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&rcc CK_BUS_VENC>;
+               access-controllers = <&rifsc 90>;
+       };
+};
\ No newline at end of file
index b2d3afb157585e6b4a28f40db0cc55058eddf1e0..27b7360e5dbaf88dfd051d2dc5b1cc1da8ca0faf 100644 (file)
        status = "okay";
 };
 
+&i2c2 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&i2c2_pins_a>;
+       pinctrl-1 = <&i2c2_sleep_pins_a>;
+       i2c-scl-rising-time-ns = <100>;
+       i2c-scl-falling-time-ns = <13>;
+       clock-frequency = <400000>;
+       status = "okay";
+};
+
+&i2c8 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&i2c8_pins_a>;
+       pinctrl-1 = <&i2c8_sleep_pins_a>;
+       i2c-scl-rising-time-ns = <57>;
+       i2c-scl-falling-time-ns = <7>;
+       clock-frequency = <400000>;
+       status = "disabled";
+};
+
 &sdmmc1 {
        pinctrl-names = "default", "opendrain", "sleep";
        pinctrl-0 = <&sdmmc1_b4_pins_a>;
        status = "okay";
 };
 
+&spi3 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&spi3_pins_a>;
+       pinctrl-1 = <&spi3_sleep_pins_a>;
+       status = "disabled";
+};
+
+&spi8 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&spi8_pins_a>;
+       pinctrl-1 = <&spi8_sleep_pins_a>;
+       status = "disabled";
+};
+
 &usart2 {
        pinctrl-names = "default", "idle", "sleep";
        pinctrl-0 = <&usart2_pins_a>;
index 53d616c3cfed793cf0e0a44e04999ed47fc24cf7..71e4bfcc9e8128ff2c6a0ce358e7cc55941e6d3e 100644 (file)
@@ -88,7 +88,7 @@
        };
 
        pmu {
-               compatible = "arm,cortex-a53-pmu", "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
index 047a83cee6038394ebe3082fdb0bfb1d578f767c..690b4ed9c29b928216832b6e82ffe6cbb9ad7333 100644 (file)
        };
 
        arm-pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a72-pmu";
                interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
index 9a722c2473fb7c3330a576188e22dbb1995d483c..2c327cc320cfc5543f33c325d96efd475b09792f 100644 (file)
@@ -48,6 +48,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-pcie.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-hummingboard-t-usb3.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-rdk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am642-phyboard-electra-gpio-fan.dtbo
 dtb-$(CONFIG_ARCH_K3) += k3-am642-sk.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am642-tqma64xxl-mbax4xxl.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
@@ -131,6 +132,8 @@ k3-am62p5-sk-csi2-tevi-ov5640-dtbs := k3-am62p5-sk.dtb \
        k3-am62x-sk-csi2-tevi-ov5640.dtbo
 k3-am642-evm-icssg1-dualemac-dtbs := \
        k3-am642-evm.dtb k3-am642-evm-icssg1-dualemac.dtbo
+k3-am642-phyboard-electra-gpio-fan-dtbs := \
+       k3-am642-phyboard-electra-rdk.dtb k3-am642-phyboard-electra-gpio-fan.dtbo
 k3-am642-tqma64xxl-mbax4xxl-sdcard-dtbs := \
        k3-am642-tqma64xxl-mbax4xxl.dtb k3-am64-tqma64xxl-mbax4xxl-sdcard.dtbo
 k3-am642-tqma64xxl-mbax4xxl-wlan-dtbs := \
@@ -161,19 +164,21 @@ dtb- += k3-am625-beagleplay-csi2-ov5640.dtb \
        k3-am642-evm-icssg1-dualemac.dtb \
        k3-am642-tqma64xxl-mbax4xxl-sdcard.dtb \
        k3-am642-tqma64xxl-mbax4xxl-wlan.dtb \
-       k3-am68-sk-base-board-csi2-dual-imx219-dtbs \
-       k3-am69-sk-csi2-dual-imx219-dtbs \
+       k3-am68-sk-base-board-csi2-dual-imx219.dtb \
+       k3-am69-sk-csi2-dual-imx219.dtb \
        k3-j721e-evm-pcie0-ep.dtb \
-       k3-j721e-sk-csi2-dual-imx219-dtbs \
+       k3-j721e-sk-csi2-dual-imx219.dtb \
        k3-j721s2-evm-pcie1-ep.dtb
 
 # Enable support for device-tree overlays
 DTC_FLAGS_k3-am625-beagleplay += -@
+DTC_FLAGS_k3-am625-phyboard-lyra-rdk += -@
 DTC_FLAGS_k3-am625-sk += -@
 DTC_FLAGS_k3-am62-lp-sk += -@
 DTC_FLAGS_k3-am62a7-sk += -@
 DTC_FLAGS_k3-am62p5-sk += -@
 DTC_FLAGS_k3-am642-evm += -@
+DTC_FLAGS_k3-am642-phyboard-electra-rdk += -@
 DTC_FLAGS_k3-am642-tqma64xxl-mbax4xxl += -@
 DTC_FLAGS_k3-am6548-iot2050-advanced-m2 += -@
 DTC_FLAGS_k3-am68-sk-base-board += -@
index c4149059a4c5bcf4f2c59dbbdd45f9048663bfa3..9a17bd3e59c90f69c4465225e158dacb33db8abc 100644 (file)
 
                interrupt-parent = <&gic500>;
                interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-               ti,power-button;
 
                regulators {
                        buck1_reg: buck1 {
index e9cffca073efcd59216b71f089dd13439887a21b..448a59dc53a77c9bc6dca12d0914118eb85141da 100644 (file)
 
        usbss0: dwc3-usb@f900000 {
                compatible = "ti,am62-usb";
-               reg = <0x00 0x0f900000 0x00 0x800>;
+               reg = <0x00 0x0f900000 0x00 0x800>,
+                     <0x00 0x0f908000 0x00 0x400>;
                clocks = <&k3_clks 161 3>;
                clock-names = "ref";
-               ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+               ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
                #address-cells = <2>;
                #size-cells = <2>;
                power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
 
        usbss1: dwc3-usb@f910000 {
                compatible = "ti,am62-usb";
-               reg = <0x00 0x0f910000 0x00 0x800>;
+               reg = <0x00 0x0f910000 0x00 0x800>,
+                     <0x00 0x0f918000 0x00 0x400>;
                clocks = <&k3_clks 162 3>;
                clock-names = "ref";
-               ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+               ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
                #address-cells = <2>;
                #size-cells = <2>;
                power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
index 6c4cec8728e4984870bf9c90de38c72176889679..e8f4d136e5dfb4dd67c16f450141ebf9cd498b24 100644 (file)
@@ -22,6 +22,7 @@
                simple-audio-card,format = "i2s";
                simple-audio-card,frame-master = <&codec_dai>;
                simple-audio-card,name = "verdin-wm8904";
+               simple-audio-card,mclk-fs = <256>;
                simple-audio-card,routing =
                        "Headphone Jack", "HPOUTL",
                        "Headphone Jack", "HPOUTR",
@@ -35,7 +36,6 @@
                        "Line", "Line In Jack";
 
                codec_dai: simple-audio-card,codec {
-                       clocks = <&audio_refclk1>;
                        sound-dai = <&wm8904_1a>;
                };
 
                        sound-dai = <&mcasp0>;
                };
        };
+
+       reg_usb_hub: regulator-usb-hub {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+               regulator-boot-on;
+               regulator-name = "HUB_PWR_EN";
+       };
 };
 
 /* Verdin ETHs */
        pinctrl-0 = <&pinctrl_gpio_1>,
                    <&pinctrl_gpio_2>,
                    <&pinctrl_gpio_3>,
-                   <&pinctrl_gpio_4>;
+                   <&pinctrl_gpio_4>,
+                   <&pinctrl_pcie_1_reset>;
 };
 
 /* Verdin I2C_3_HDMI */
        status = "okay";
 };
 
+/* Do not force CTRL_SLEEP_MOCI# always enabled */
+&reg_force_sleep_moci {
+       status = "disabled";
+};
+
 /* Verdin SD_1 */
 &sdhci1 {
        status = "okay";
 };
 
 &usb1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
        status = "okay";
+
+       usb-hub@1 {
+               compatible = "usb424,2744";
+               reg = <1>;
+               vdd-supply = <&reg_usb_hub>;
+       };
 };
 
 /* Verdin CTRL_WAKE1_MICO# */
        status = "okay";
 };
 
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+       status = "okay";
+};
+
 /* Verdin UART_2 */
 &wkup_uart0 {
        status = "okay";
index be62648e7818aeedccbc1942776fff87f69a1f60..74eec1a1abca9f9414e9ed6d6f268101f0b22858 100644 (file)
        pinctrl-0 = <&pinctrl_gpio_1>,
                    <&pinctrl_gpio_2>,
                    <&pinctrl_gpio_3>,
-                   <&pinctrl_gpio_4>;
+                   <&pinctrl_gpio_4>,
+                   <&pinctrl_pcie_1_reset>;
 };
 
 /* Verdin I2C_3_HDMI */
        status = "okay";
 };
 
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+       status = "okay";
+};
+
 /* Verdin UART_2 */
 &wkup_uart0 {
        status = "okay";
index 77b1beb638ad7bf400c0b7df836d0ea032e0f60f..754216d8ac1424deefd30d8094d065ce255ba814 100644 (file)
 &main_gpio0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_ctrl_sleep_moci>,
-                   <&pinctrl_gpio_1>,
-                   <&pinctrl_gpio_2>,
-                   <&pinctrl_gpio_3>,
-                   <&pinctrl_gpio_4>;
+                   <&pinctrl_gpio_5>,
+                   <&pinctrl_gpio_6>,
+                   <&pinctrl_gpio_7>,
+                   <&pinctrl_gpio_8>;
 };
 
 /* Verdin I2C_1 */
        status = "okay";
 };
 
+&mcu_gpio0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpio_1>,
+                   <&pinctrl_gpio_2>,
+                   <&pinctrl_gpio_3>,
+                   <&pinctrl_gpio_4>,
+                   <&pinctrl_pcie_1_reset>;
+};
+
 /* Verdin I2C_3_HDMI */
 &mcu_i2c0 {
        status = "okay";
        status = "okay";
 };
 
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+       status = "okay";
+};
+
 /* Verdin UART_2 */
 &wkup_uart0 {
        status = "okay";
index 997dfafd27eb463e3d4e8f1867062e1e9f66078e..7372d392ec8a349b97b1787fd0ee0b946e3926e5 100644 (file)
        pinctrl-0 = <&pinctrl_gpio_1>,
                    <&pinctrl_gpio_2>,
                    <&pinctrl_gpio_3>,
-                   <&pinctrl_gpio_4>;
+                   <&pinctrl_gpio_4>,
+                   <&pinctrl_pcie_1_reset>;
 };
 
 /* Verdin I2C_3_HDMI */
        status = "okay";
 };
 
+/* Verdin PCIE_1_RESET# */
+&verdin_pcie_1_reset_hog {
+       status = "okay";
+};
+
 /* Verdin UART_2 */
 &wkup_uart0 {
        status = "okay";
index e8d8857ad51ff2f25d4ed4ec6989fb19e9e39354..2038c5e04639086c82442a8b925fbf5bcc1c4334 100644 (file)
@@ -76,7 +76,7 @@
 
        memory@80000000 {
                device_type = "memory";
-               reg = <0x00000000 0x80000000 0x00000000 0x40000000>; /* 1G RAM */
+               reg = <0x00000000 0x80000000 0x00000000 0x80000000>; /* 2G RAM */
        };
 
        opp-table {
                vin-supply = <&reg_1v8>;
        };
 
+       /*
+        * By default we enable CTRL_SLEEP_MOCI#, this is required to have
+        * peripherals on the carrier board powered.
+        * If more granularity or power saving is required this can be disabled
+        * in the carrier board device tree files.
+        */
+       reg_force_sleep_moci: regulator-force-sleep-moci {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+               gpio = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "CTRL_SLEEP_MOCI#";
+       };
+
        /* Verdin SD_1 Power Supply */
        reg_sdhc1_vmmc: regulator-sdhci1 {
                compatible = "regulator-fixed";
                >;
        };
 
+       /* Verdin SD_1_CD# as GPIO */
+       pinctrl_sd1_cd_gpio: main-gpio1-48-default-pins {
+               pinctrl-single,pins = <
+                       AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 7) /* (D17) MMC1_SDCD.GPIO1_48 */ /* SODIMM 84 */
+               >;
+       };
+
        /* Verdin DSI_1_INT# (pulled-up as active-low) */
        pinctrl_dsi1_int: main-gpio1-49-default-pins {
                pinctrl-single,pins = <
                        AM62X_IOPAD(0x22c, PIN_INPUT,        0) /* (B21) MMC1_DAT1 */ /* SODIMM 82 */
                        AM62X_IOPAD(0x228, PIN_INPUT,        0) /* (C21) MMC1_DAT2 */ /* SODIMM 70 */
                        AM62X_IOPAD(0x224, PIN_INPUT,        0) /* (D22) MMC1_DAT3 */ /* SODIMM 72 */
-                       AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 0) /* (D17) MMC1_SDCD */ /* SODIMM 84 */
                >;
        };
 
                "",
                "",
                "";
-
-       verdin_ctrl_sleep_moci: ctrl-sleep-moci-hog {
-               gpio-hog;
-               /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
-               gpios = <31 GPIO_ACTIVE_HIGH>;
-               line-name = "CTRL_SLEEP_MOCI#";
-               output-high;
-       };
 };
 
 &main_gpio1 {
                "",
                "",
                "";
+
+       verdin_pcie_1_reset_hog: pcie-1-reset-hog {
+               gpio-hog;
+               /* Verdin PCIE_1_RESET# (SODIMM 244) */
+               gpios = <0 GPIO_ACTIVE_LOW>;
+               line-name = "PCIE_1_RESET#";
+               output-low;
+               status = "disabled";
+       };
 };
 
 /* Verdin CAN_2 */
 /* Verdin SD_1 */
 &sdhci1 {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_sdhci1>;
+       pinctrl-0 = <&pinctrl_sdhci1>, <&pinctrl_sd1_cd_gpio>;
+       cd-gpios = <&main_gpio1 48 GPIO_ACTIVE_LOW>;
        disable-wp;
        vmmc-supply = <&reg_sdhc1_vmmc>;
        vqmmc-supply = <&reg_sdhc1_vqmmc>;
+       ti,fails-without-test-cd;
        status = "disabled";
 };
 
index 23ce1bfda8d6abbb75472d3b8a321f6e9eb3d8c3..66ddf2dc51afa7870a27ebabac19799726a834aa 100644 (file)
                        compatible = "ti,am654-chipid";
                        reg = <0x14 0x4>;
                };
+
+               usb0_phy_ctrl: syscon@4008 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4008 0x4>;
+               };
+
+               usb1_phy_ctrl: syscon@4018 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4018 0x4>;
+               };
        };
 
        target-module@2b300050 {
index a34e0df2ab8646206b26c19f529629f9dfedf226..18e3070a86839f7a4c3816037bf71781e5a3441b 100644 (file)
                };
        };
 
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_en_pins_default>;
+               /* Internal power on time(Figure 8-3) * 2 */
+               post-power-on-delay-ms = <10>;
+               /* Re-enable time(Figure 8-2) + 20uS */
+               power-off-delay-us = <80>;
+               reset-gpios = <&main_gpio0 38 GPIO_ACTIVE_LOW>;
+       };
+
        vsys_5v0: regulator-1 {
                bootph-all;
                compatible = "regulator-fixed";
                regulator-boot-on;
        };
 
-       wlan_en: regulator-3 {
-               /* OUTPUT of SN74AVC2T244DQMR */
-               compatible = "regulator-fixed";
-               regulator-name = "wlan_en";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
-               enable-active-high;
-               regulator-always-on;
-               vin-supply = <&vdd_3v3>;
-               gpio = <&main_gpio0 38 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&wifi_en_pins_default>;
-       };
-
        vdd_3v3_sd: regulator-4 {
                /* output of TPS22918DBVR-U21 */
                bootph-all;
                pinctrl-single,pins = <
                        AM62X_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AD24) MDIO0_MDC */
                        AM62X_IOPAD(0x015c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */
+                       AM62X_IOPAD(0x003c, PIN_INPUT, 7) /* (M25) GPMC0_AD0.GPIO0_15 */
+                       AM62X_IOPAD(0x018c, PIN_INPUT, 7) /* (AC21) RGMII2_RD2.GPIO1_5 */
                >;
        };
 
                        AM62X_IOPAD(0x016c, PIN_INPUT, 1) /* (Y18) RGMII2_TD0.RMII2_TXD0 */
                        AM62X_IOPAD(0x0170, PIN_INPUT, 1) /* (AA18) RGMII2_TD1.RMII2_TXD1 */
                        AM62X_IOPAD(0x0164, PIN_INPUT, 1) /* (AA19) RGMII2_TX_CTL.RMII2_TX_EN */
-                       AM62X_IOPAD(0x018c, PIN_OUTPUT, 7) /* (AC21) RGMII2_RD2.GPIO1_5 */
                        AM62X_IOPAD(0x0190, PIN_INPUT, 7) /* (AE22) RGMII2_RD3.GPIO1_6 */
                        AM62X_IOPAD(0x01f0, PIN_OUTPUT, 5) /* (A18) EXT_REFCLK1.CLKOUT0 */
                >;
 
        cpsw3g_phy0: ethernet-phy@0 {
                reg = <0>;
+               reset-gpios = <&main_gpio0 15 GPIO_ACTIVE_LOW>;
+               reset-assert-us = <10000>;
+               reset-deassert-us = <50000>;
        };
 
        cpsw3g_phy1: ethernet-phy@1 {
                "USR0", "USR1", "USR2", "USR3", "", "", "USR4", /* 3-9 */
                "EEPROM_WP",                                    /* 10 */
                "CSI2_CAMERA_GPIO1", "CSI2_CAMERA_GPIO2",       /* 11-12 */
-               "CC1352P7_BOOT", "CC1352P7_RSTN", "", "", "",   /* 13-17 */
+               "CC1352P7_BOOT", "CC1352P7_RSTN", "GBE_RSTN", "", "",   /* 13-17 */
                "USR_BUTTON", "", "", "", "", "", "", "", "",   /* 18-26 */
                "", "", "", "", "", "", "", "", "", "HDMI_INT", /* 27-36 */
                "", "VDD_WLAN_EN", "", "", "WL_IRQ", "GBE_INTN",/* 37-42 */
 };
 
 &sdhci2 {
-       vmmc-supply = <&wlan_en>;
        pinctrl-names = "default";
        pinctrl-0 = <&wifi_pins_default>, <&wifi_32k_clk>;
        non-removable;
        ti,fails-without-test-cd;
        cap-power-off-card;
        keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
        assigned-clocks = <&k3_clks 157 158>;
        assigned-clock-parents = <&k3_clks 157 160>;
        #address-cells = <1>;
index a83a90497857662d7d0fc51e9d530949ffc51f79..50d2573c840ee9bb553d778e07b4e0aad279ef55 100644 (file)
@@ -31,7 +31,7 @@
        can_tc1: can-phy0 {
                compatible = "ti,tcan1042";
                #phy-cells = <0>;
-               max-bitrate = <5000000>;
+               max-bitrate = <8000000>;
                standby-gpios = <&gpio_exp 1 GPIO_ACTIVE_HIGH>;
        };
 
                };
        };
 
+       sound {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "phyBOARD-Lyra";
+               simple-audio-card,widgets =
+                       "Microphone",           "Mic Jack",
+                       "Headphone",            "Headphone Jack",
+                       "Speaker",              "External Speaker";
+               simple-audio-card,routing =
+                       "MIC3R",                "Mic Jack",
+                       "Mic Jack",             "Mic Bias",
+                       "Headphone Jack",       "HPLOUT",
+                       "Headphone Jack",       "HPROUT",
+                       "External Speaker",     "SPOP",
+                       "External Speaker",     "SPOM";
+               simple-audio-card,format = "dsp_b";
+               simple-audio-card,bitclock-master = <&sound_master>;
+               simple-audio-card,frame-master = <&sound_master>;
+               simple-audio-card,bitclock-inversion;
+
+               simple-audio-card,cpu {
+                       sound-dai = <&mcasp2>;
+               };
+
+               sound_master: simple-audio-card,codec {
+                               sound-dai = <&audio_codec>;
+                               clocks = <&audio_refclk1>;
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                };
        };
 
+       vcc_1v8: regulator-vcc-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
        vcc_3v3_mmc: regulator-vcc-3v3-mmc {
                compatible = "regulator-fixed";
                regulator-name = "VCC_3V3_MMC";
                regulator-always-on;
                regulator-boot-on;
        };
+
+       vcc_3v3_sw: regulator-vcc-3v3-sw {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_3V3_SW";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
 };
 
 &main_pmx0 {
+       audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins {
+               pinctrl-single,pins = <
+                       AM62X_IOPAD(0x0a0, PIN_OUTPUT, 1) /* (K25) GPMC0_WPn.AUDIO_EXT_REFCLK1 */
+               >;
+       };
+
        gpio_keys_pins_default: gpio-keys-default-pins {
                pinctrl-single,pins = <
                        AM62X_IOPAD(0x1d4, PIN_INPUT, 7) /* (B15) UART0_RTSn.GPIO1_23 */
                >;
        };
 
+       main_mcasp2_pins_default: main-mcasp2-default-pins {
+               pinctrl-single,pins = <
+                       AM62X_IOPAD(0x070, PIN_INPUT, 3) /* (T24) GPMC0_AD13.MCASP2_ACLKX */
+                       AM62X_IOPAD(0x06c, PIN_INPUT, 3) /* (T22) GPMC0_AD12.MCASP2_AFSX */
+                       AM62X_IOPAD(0x064, PIN_OUTPUT, 3) /* (T25) GPMC0_AD10.MCASP2_AXR2 */
+                       AM62X_IOPAD(0x068, PIN_INPUT, 3) /* (R21) GPMC0_AD11.MCASP2_AXR3 */
+               >;
+       };
+
        main_mmc1_pins_default: main-mmc1-default-pins {
                pinctrl-single,pins = <
                        AM62X_IOPAD(0x23c, PIN_INPUT_PULLUP, 0) /* (A21) MMC1_CMD */
        clock-frequency = <100000>;
        status = "okay";
 
+       audio_codec: audio-codec@18 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&audio_ext_refclk1_pins_default>;
+
+               #sound-dai-cells = <0>;
+               compatible = "ti,tlv320aic3007";
+               reg = <0x18>;
+               ai3x-micbias-vg = <2>;
+
+               AVDD-supply = <&vcc_3v3_sw>;
+               IOVDD-supply = <&vcc_3v3_sw>;
+               DRVDD-supply = <&vcc_3v3_sw>;
+               DVDD-supply = <&vcc_1v8>;
+       };
+
        gpio_exp: gpio-expander@21 {
                pinctrl-names = "default";
                pinctrl-0 = <&gpio_exp_int_pins_default>;
                                  "GPIO6_ETH1_USER_RESET", "GPIO7_AUDIO_USER_RESET";
        };
 
+       usb-pd@22 {
+               compatible = "ti,tps6598x";
+               reg = <0x22>;
+
+               connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       self-powered;
+                       data-role = "dual";
+                       power-role = "sink";
+                       port {
+                               usb_con_hs: endpoint {
+                                       remote-endpoint = <&typec_hs>;
+                               };
+                       };
+               };
+       };
+
        sii9022: bridge-hdmi@39 {
                compatible = "sil,sii9022";
                reg = <0x39>;
        status = "okay";
 };
 
+&mcasp2 {
+       #sound-dai-cells = <0>;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_mcasp2_pins_default>;
+
+       /* MCASP_IIS_MODE */
+       op-mode = <0>;
+       tdm-slots = <2>;
+
+       /* 0: INACTIVE, 1: TX, 2: RX */
+       serial-dir = <
+                       0 0 1 2
+                       0 0 0 0
+                       0 0 0 0
+                       0 0 0 0
+       >;
+       tx-num-evt = <32>;
+       rx-num-evt = <32>;
+       status = "okay";
+};
+
 &sdhci1 {
        vmmc-supply = <&vcc_3v3_mmc>;
        vqmmc-supply = <&vddshv5_sdio>;
 };
 
 &usb0 {
-       dr_mode = "peripheral";
+       usb-role-switch;
+
+       port {
+               typec_hs: endpoint {
+                       remote-endpoint = <&usb_con_hs>;
+               };
+       };
 };
 
 &usb1 {
index aa1e057082f0829f5d09dccdfcf596c486cb7230..bf9c2d9c6439a90c04db51bb123972fa1b5fbd6d 100644 (file)
                ti,itap-del-sel-sd-hs = <0x0>;
                ti,itap-del-sel-sdr12 = <0x0>;
                ti,itap-del-sel-sdr25 = <0x0>;
-               no-1-8-v;
                status = "disabled";
        };
 
                ti,itap-del-sel-sd-hs = <0x0>;
                ti,itap-del-sel-sdr12 = <0x0>;
                ti,itap-del-sel-sdr25 = <0x0>;
-               no-1-8-v;
                status = "disabled";
        };
 
        usbss0: dwc3-usb@f900000 {
                compatible = "ti,am62-usb";
-               reg = <0x00 0x0f900000 0x00 0x800>;
+               reg = <0x00 0x0f900000 0x00 0x800>,
+                     <0x00 0x0f908000 0x00 0x400>;
                clocks = <&k3_clks 161 3>;
                clock-names = "ref";
-               ti,syscon-phy-pll-refclk = <&wkup_conf 0x4008>;
+               ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
                #address-cells = <2>;
                #size-cells = <2>;
                power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
                        interrupt-names = "host", "peripheral";
                        maximum-speed = "high-speed";
                        dr_mode = "otg";
+                       snps,usb2-gadget-lpm-disable;
+                       snps,usb2-lpm-disable;
                };
        };
 
        usbss1: dwc3-usb@f910000 {
                compatible = "ti,am62-usb";
-               reg = <0x00 0x0f910000 0x00 0x800>;
+               reg = <0x00 0x0f910000 0x00 0x800>,
+                     <0x00 0x0f918000 0x00 0x400>;
                clocks = <&k3_clks 162 3>;
                clock-names = "ref";
-               ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
+               ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
                #address-cells = <2>;
                #size-cells = <2>;
                power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
                        interrupt-names = "host", "peripheral";
                        maximum-speed = "high-speed";
                        dr_mode = "otg";
+                       snps,usb2-gadget-lpm-disable;
+                       snps,usb2-lpm-disable;
                };
        };
 
                        #size-cells = <0>;
                };
        };
+
+       vpu: video-codec@30210000 {
+               compatible = "ti,j721s2-wave521c", "cnm,wave521c";
+               reg = <0x00 0x30210000 0x00 0x10000>;
+               clocks = <&k3_clks 204 2>;
+               power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>;
+       };
 };
index f7bec484705ad61f894aa58d91c4e1bb4feb3029..98043e9aa316b82f1c781eb1f4c84dded1e81ec6 100644 (file)
                        compatible = "ti,am654-chipid";
                        reg = <0x14 0x4>;
                };
+
+               usb0_phy_ctrl: syscon@4008 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4008 0x4>;
+               };
+
+               usb1_phy_ctrl: syscon@4018 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4018 0x4>;
+               };
        };
 
        wkup_uart0: serial@2b300000 {
index f241637a5642a0407921fa18b8d66a311bde1197..fa43cd0b631e62af66eb962c80e88e67696eb074 100644 (file)
                regulator-boot-on;
        };
 
+       vddshv_sdio: regulator-5 {
+               compatible = "regulator-gpio";
+               regulator-name = "vddshv_sdio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&vddshv_sdio_pins_default>;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               vin-supply = <&ldo1>;
+               gpios = <&main_gpio0 31 GPIO_ACTIVE_HIGH>;
+               states = <1800000 0x0>,
+                        <3300000 0x1>;
+       };
+
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                        AM62AX_IOPAD(0x01d4, PIN_INPUT, 7) /* (C15) UART0_RTSn.GPIO1_23 */
                >;
        };
+
+       vddshv_sdio_pins_default: vddshv-sdio-default-pins {
+               pinctrl-single,pins = <
+                       AM62AX_IOPAD(0x07c, PIN_OUTPUT, 7) /* (M19) GPMC0_CLK.GPIO0_31 */
+               >;
+       };
 };
 
 &mcu_pmx0 {
        /* SD/MMC */
        status = "okay";
        vmmc-supply = <&vdd_mmc1>;
+       vqmmc-supply = <&vddshv_sdio>;
        pinctrl-names = "default";
        pinctrl-0 = <&main_mmc1_pins_default>;
        disable-wp;
index 7337a9e1353542bfcb8633ea1306defb54e4b476..900d1f9530a2a118cb3d40005e115050d0182d11 100644 (file)
                status = "disabled";
        };
 
+       usbss0: usb@f900000 {
+               compatible = "ti,am62-usb";
+               reg = <0x00 0x0f900000 0x00 0x800>,
+                     <0x00 0x0f908000 0x00 0x400>;
+               clocks = <&k3_clks 161 3>;
+               clock-names = "ref";
+               ti,syscon-phy-pll-refclk = <&usb0_phy_ctrl 0x0>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+               ranges;
+               status = "disabled";
+
+               usb0: usb@31000000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x00 0x31000000 0x00 0x50000>;
+                       interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+                       <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+                       interrupt-names = "host", "peripheral";
+                       maximum-speed = "high-speed";
+                       dr_mode = "otg";
+                       snps,usb2-gadget-lpm-disable;
+                       snps,usb2-lpm-disable;
+               };
+       };
+
+       usbss1: usb@f910000 {
+               compatible = "ti,am62-usb";
+               reg = <0x00 0x0f910000 0x00 0x800>,
+                     <0x00 0x0f918000 0x00 0x400>;
+               clocks = <&k3_clks 162 3>;
+               clock-names = "ref";
+               ti,syscon-phy-pll-refclk = <&usb1_phy_ctrl 0x0>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+               ranges;
+               status = "disabled";
+
+               usb1: usb@31100000 {
+                       compatible = "snps,dwc3";
+                       reg = <0x00 0x31100000 0x00 0x50000>;
+                       interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, /* irq.0 */
+                       <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; /* irq.0 */
+                       interrupt-names = "host", "peripheral";
+                       maximum-speed = "high-speed";
+                       dr_mode = "otg";
+                       snps,usb2-gadget-lpm-disable;
+                       snps,usb2-lpm-disable;
+               };
+       };
+
        fss: bus@fc00000 {
                compatible = "simple-bus";
                reg = <0x00 0x0fc00000 0x00 0x70000>;
                assigned-clock-parents = <&k3_clks 13 11>;
                clock-names = "fck";
                power-domains = <&k3_pds 13 TI_SCI_PD_EXCLUSIVE>;
+               status = "disabled";
 
                dmas = <&main_pktdma 0xc600 15>,
                       <&main_pktdma 0xc601 15>,
                                label = "port1";
                                phys = <&phy_gmii_sel 1>;
                                mac-address = [00 00 00 00 00 00];
+                               status = "disabled";
                        };
 
                        cpsw_port2: port@2 {
                                label = "port2";
                                phys = <&phy_gmii_sel 2>;
                                mac-address = [00 00 00 00 00 00];
+                               status = "disabled";
                        };
                };
 
index a84756c336d0569081d2f382984ff95141ac7319..c71d9624ea27712c6034679d0ea8fe31395bdc20 100644 (file)
                        reg = <0x14 0x4>;
                        bootph-all;
                };
+
+               usb0_phy_ctrl: syscon@4008 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4008 0x4>;
+               };
+
+               usb1_phy_ctrl: syscon@4018 {
+                       compatible = "ti,am62-usb-phy-ctrl", "syscon";
+                       reg = <0x4018 0x4>;
+               };
        };
 
        wkup_uart0: serial@2b300000 {
index e86f34e835c1ad2d2410a648f2758a909aaa5f22..6e72346591113d8677f0a6e462bd53f05eca604c 100644 (file)
@@ -27,6 +27,8 @@
                spi0 = &ospi0;
                ethernet0 = &cpsw_port1;
                ethernet1 = &cpsw_port2;
+               usb0 = &usb0;
+               usb1 = &usb1;
        };
 
        chosen {
                bootph-all;
        };
 
+       main_usb1_pins_default: main-usb1-default-pins {
+               pinctrl-single,pins = <
+                       AM62PX_IOPAD(0x0258, PIN_INPUT, 0) /* (G21) USB1_DRVVBUS */
+               >;
+       };
+
        main_wlirq_pins_default: main-wlirq-default-pins {
                pinctrl-single,pins = <
                        AM62PX_IOPAD(0x0128, PIN_INPUT, 7) /* (K25) MMC2_SDWP.GPIO0_72 */
        };
 };
 
+&main_i2c0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c0_pins_default>;
+       clock-frequency = <400000>;
+
+       typec_pd0: usb-power-controller@3f {
+               compatible = "ti,tps6598x";
+               reg = <0x3f>;
+
+               connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       self-powered;
+                       data-role = "dual";
+                       power-role = "sink";
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               port@0 {
+                                       reg = <0>;
+                                       usb_con_hs: endpoint {
+                                               remote-endpoint = <&usb0_hs_ep>;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
 &main_i2c1 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-names = "default";
        pinctrl-0 = <&main_rgmii1_pins_default>,
                    <&main_rgmii2_pins_default>;
+       status = "okay";
 };
 
 &cpsw_port1 {
        phy-mode = "rgmii-rxid";
        phy-handle = <&cpsw3g_phy0>;
+       status = "okay";
 };
 
 &cpsw_port2 {
        phy-mode = "rgmii-rxid";
        phy-handle = <&cpsw3g_phy1>;
+       status = "okay";
 };
 
 &cpsw3g_mdio {
        };
 };
 
+&usbss0 {
+       status = "okay";
+       ti,vbus-divider;
+};
+
+&usbss1 {
+       status = "okay";
+       ti,vbus-divider;
+};
+
+&usb0 {
+       usb-role-switch;
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       port@0 {
+               reg = <0>;
+               usb0_hs_ep: endpoint {
+                       remote-endpoint = <&usb_con_hs>;
+               };
+       };
+};
+
+&usb1 {
+       dr_mode = "host";
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_usb1_pins_default>;
+};
+
 &mcasp1 {
        status = "okay";
        #sound-dai-cells = <0>;
        pinctrl-0 = <&ospi0_pins_default>;
        bootph-all;
 
-       flash@0{
+       flash@0 {
                compatible = "jedec,spi-nor";
                reg = <0x0>;
                spi-tx-bus-width = <8>;
index 53fe1d065ddbbe2fb616d50d5f75685b0b66578f..e20e4ffd0f1faee877aa1f76b4df0f31a24f1797 100644 (file)
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&main_uart0_pins_default>;
-       current-speed = <115200>;
 };
 
 /* main_uart1 is reserved for firmware usage */
diff --git a/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso b/arch/arm64/boot/dts/ti/k3-am642-phyboard-electra-gpio-fan.dtso
new file mode 100644 (file)
index 0000000..5057658
--- /dev/null
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2024 PHYTEC America LLC
+ * Author: Nathan Morrisson <nmorrisson@phytec.com>
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+#include "k3-pinctrl.h"
+
+&{/} {
+       fan: gpio-fan {
+               compatible = "gpio-fan";
+               gpio-fan,speed-map = <0 0 8600 1>;
+               gpios = <&main_gpio0 28 GPIO_ACTIVE_LOW>;
+               #cooling-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_fan_pins_default>;
+       };
+};
+
+&main_pmx0 {
+       gpio_fan_pins_default: gpio-fan-default-pins {
+               pinctrl-single,pins = <
+                       AM64X_IOPAD(0x070, PIN_OUTPUT, 7) /* (V18) GPMC0_AD13.GPIO0_28 */
+               >;
+       };
+};
+
+&thermal_zones {
+       main0_thermal: main0-thermal {
+               trips {
+                       main0_thermal_trip0: main0-thermal-trip {
+                               temperature = <65000>;  /* millicelsius */
+                               hysteresis = <2000>;    /* millicelsius */
+                               type = "active";
+                       };
+               };
+
+               cooling-maps {
+                       map0 {
+                               trip = <&main0_thermal_trip0>;
+                               cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                       };
+               };
+       };
+};
index 8237b8c815b84a86874afaf8bd881889936fac5d..6df331ccb970db06fd0118e8105ff3f03a1972d2 100644 (file)
@@ -42,7 +42,7 @@
                pinctrl-names = "default";
                pinctrl-0 = <&can_tc1_pins_default>;
                #phy-cells = <0>;
-               max-bitrate = <5000000>;
+               max-bitrate = <8000000>;
                standby-gpios = <&main_gpio0 32 GPIO_ACTIVE_HIGH>;
        };
 
@@ -51,7 +51,7 @@
                pinctrl-names = "default";
                pinctrl-0 = <&can_tc2_pins_default>;
                #phy-cells = <0>;
-               max-bitrate = <5000000>;
+               max-bitrate = <8000000>;
                standby-gpios = <&main_gpio0 35 GPIO_ACTIVE_HIGH>;
        };
 
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&main_uart0_pins_default>;
-       current-speed = <115200>;
 };
 
 &main_uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&main_uart1_pins_default>;
        uart-has-rtscts;
-       current-speed = <115200>;
 };
 
 &sdhci1 {
index 67cd41bf806eab21e2d6d1d452686ecf60de573a..5b028b3a3192f2890720b12fbba81f481206573c 100644 (file)
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&main_uart0_pins_default>;
-       current-speed = <115200>;
 };
 
 &main_uart1 {
index c50a585dd6384841b13063c65ca23ea47825657d..ef7897763ef84fc45078f6a99565d15609a44331 100644 (file)
 };
 
 &icssg0_eth {
-       status = "disabled";
-};
+       compatible = "ti,am654-sr1-icssg-prueth";
 
-&icssg0_mdio {
-       status = "disabled";
+       ti,prus = <&pru0_0>, <&rtu0_0>, <&pru0_1>, <&rtu0_1>;
+       firmware-name = "ti-pruss/am65x-pru0-prueth-fw.elf",
+                       "ti-pruss/am65x-rtu0-prueth-fw.elf",
+                       "ti-pruss/am65x-pru1-prueth-fw.elf",
+                       "ti-pruss/am65x-rtu1-prueth-fw.elf";
+
+       ti,pruss-gp-mux-sel = <2>,      /* MII mode */
+                             <2>,
+                             <2>,      /* MII mode */
+                             <2>;
+
+       dmas = <&main_udmap 0xc100>, /* egress slice 0 */
+              <&main_udmap 0xc101>, /* egress slice 0 */
+              <&main_udmap 0xc102>, /* egress slice 0 */
+              <&main_udmap 0xc103>, /* egress slice 0 */
+              <&main_udmap 0xc104>, /* egress slice 1 */
+              <&main_udmap 0xc105>, /* egress slice 1 */
+              <&main_udmap 0xc106>, /* egress slice 1 */
+              <&main_udmap 0xc107>, /* egress slice 1 */
+              <&main_udmap 0x4100>, /* ingress slice 0 */
+              <&main_udmap 0x4101>, /* ingress slice 1 */
+              <&main_udmap 0x4102>, /* mgmnt rsp slice 0 */
+              <&main_udmap 0x4103>; /* mgmnt rsp slice 1 */
+       dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
+                   "tx1-0", "tx1-1", "tx1-2", "tx1-3",
+                   "rx0", "rx1",
+                   "rxmgm0", "rxmgm1";
 };
index ff857117d71937b132468ceb915500eb533fcb9a..ed71561c5bd9a9266225d0f4673fdc1962c33f39 100644 (file)
@@ -66,7 +66,7 @@
                assigned-clock-parents = <&k3_clks 153 8>, <&k3_clks 153 4>;
                ti,serdes-clk = <&serdes0_clk>;
                #clock-cells = <1>;
-               mux-controls = <&serdes_mux 0>;
+               mux-controls = <&serdes0_mux 0>;
        };
 
        serdes1: serdes@910000 {
@@ -81,7 +81,7 @@
                assigned-clock-parents = <&k3_clks 154 9>, <&k3_clks 154 5>;
                ti,serdes-clk = <&serdes1_clk>;
                #clock-cells = <1>;
-               mux-controls = <&serdes_mux 1>;
+               mux-controls = <&serdes1_mux 0>;
        };
 
        main_uart0: serial@2800000 {
@@ -89,7 +89,6 @@
                reg = <0x00 0x02800000 0x00 0x100>;
                interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
                status = "disabled";
        };
                interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
                mmc-ddr-1_8v;
                mmc-hs200-1_8v;
+               ti,clkbuf-sel = <0x7>;
+               ti,trm-icp = <0x8>;
                ti,otap-del-sel-legacy = <0x0>;
                ti,otap-del-sel-mmc-hs = <0x0>;
-               ti,otap-del-sel-sd-hs = <0x0>;
-               ti,otap-del-sel-sdr12 = <0x0>;
-               ti,otap-del-sel-sdr25 = <0x0>;
-               ti,otap-del-sel-sdr50 = <0x8>;
-               ti,otap-del-sel-sdr104 = <0x7>;
-               ti,otap-del-sel-ddr50 = <0x5>;
                ti,otap-del-sel-ddr52 = <0x5>;
                ti,otap-del-sel-hs200 = <0x5>;
-               ti,otap-del-sel-hs400 = <0x0>;
-               ti,trm-icp = <0x8>;
+               ti,itap-del-sel-ddr52 = <0x0>;
                dma-coherent;
                status = "disabled";
        };
                clocks = <&k3_clks 48 0>, <&k3_clks 48 1>;
                clock-names = "clk_ahb", "clk_xin";
                interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+               ti,clkbuf-sel = <0x7>;
+               ti,trm-icp = <0x8>;
                ti,otap-del-sel-legacy = <0x0>;
-               ti,otap-del-sel-mmc-hs = <0x0>;
                ti,otap-del-sel-sd-hs = <0x0>;
-               ti,otap-del-sel-sdr12 = <0x0>;
-               ti,otap-del-sel-sdr25 = <0x0>;
+               ti,otap-del-sel-sdr12 = <0xf>;
+               ti,otap-del-sel-sdr25 = <0xf>;
                ti,otap-del-sel-sdr50 = <0x8>;
                ti,otap-del-sel-sdr104 = <0x7>;
                ti,otap-del-sel-ddr50 = <0x4>;
-               ti,otap-del-sel-ddr52 = <0x4>;
-               ti,otap-del-sel-hs200 = <0x7>;
-               ti,clkbuf-sel = <0x7>;
-               ti,trm-icp = <0x8>;
+               ti,itap-del-sel-legacy = <0xa>;
+               ti,itap-del-sel-sd-hs = <0x1>;
+               ti,itap-del-sel-sdr12 = <0xa>;
+               ti,itap-del-sel-sdr25 = <0x1>;
                dma-coherent;
                status = "disabled";
        };
                ranges = <0x0 0x0 0x00100000 0x1c000>;
 
                serdes0_clk: clock@4080 {
-                       compatible = "syscon";
-                       reg = <0x00004080 0x4>;
+                       compatible = "ti,am654-serdes-ctrl", "syscon";
+                       reg = <0x4080 0x4>;
+
+                       serdes0_mux: mux-controller {
+                               compatible = "mmio-mux";
+                               #mux-control-cells = <1>;
+                               mux-reg-masks = <0x0 0x3>; /* lane select */
+                       };
                };
 
                serdes1_clk: clock@4090 {
-                       compatible = "syscon";
-                       reg = <0x00004090 0x4>;
-               };
+                       compatible = "ti,am654-serdes-ctrl", "syscon";
+                       reg = <0x4090 0x4>;
 
-               serdes_mux: mux-controller {
-                       compatible = "mmio-mux";
-                       #mux-control-cells = <1>;
-                       mux-reg-masks = <0x4080 0x3>, /* SERDES0 lane select */
-                                       <0x4090 0x3>; /* SERDES1 lane select */
+                       serdes1_mux: mux-controller {
+                               compatible = "mmio-mux";
+                               #mux-control-cells = <1>;
+                               mux-reg-masks = <0x0 0x3>; /* lane select */
+                       };
                };
 
                dss_oldi_io_ctrl: dss-oldi-io-ctrl@41e0 {
index 6ff3ccc39fb448c4ca9fd642740ff77bb20b558b..8feab93176447912e85d86571d1fb42ab61f3ad3 100644 (file)
@@ -43,7 +43,6 @@
                reg = <0x00 0x40a00000 0x00 0x100>;
                interrupts = <GIC_SPI 565 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <96000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
                status = "disabled";
        };
                compatible = "simple-bus";
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges;
+               ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+                        <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+                        <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+                        <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* OSPI0 Memory */
+                        <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
 
                ospi0: spi@47040000 {
                        compatible = "ti,am654-ospi", "cdns,qspi-nor";
index 37527890ddeaf9a5517d037deb7d7e98696e638d..eee072e44a42f5f66423200975016447d22bdc46 100644 (file)
@@ -59,7 +59,6 @@
                reg = <0x42300000 0x100>;
                interrupts = <GIC_SPI 697 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
                status = "disabled";
        };
index 50de2a448a3a684ed9034a834cbf5084277270ac..d88651c297a22a52b499fd34f3e4d8f16e8af2fe 100644 (file)
        wkup_uart0_pins_default: wkup-uart0-default-pins {
                bootph-all;
                pinctrl-single,pins = <
-                       J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-                       J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
-                       J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
-                       J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
+                       J784S4_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_UART0_CTSn */
+                       J784S4_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (L36) WKUP_UART0_RTSn */
+                       J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
+                       J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
                >;
        };
 
        wkup_i2c0_pins_default: wkup-i2c0-default-pins {
                bootph-all;
                pinctrl-single,pins = <
-                       J721S2_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
-                       J721S2_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
+                       J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
+                       J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
                >;
        };
 
index 657f9cc9f4ea017f034a3d83ac30a8b5325b9dab..9386bf3ef9f684474c817e22f0bbf657185b192d 100644 (file)
                reg = <0x00 0x02800000 0x00 0x100>;
                interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 146 2>;
                clock-names = "fclk";
                reg = <0x00 0x02810000 0x00 0x100>;
                interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 278 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 278 2>;
                clock-names = "fclk";
                reg = <0x00 0x02820000 0x00 0x100>;
                interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 279 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 279 2>;
                clock-names = "fclk";
                reg = <0x00 0x02830000 0x00 0x100>;
                interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 280 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 280 2>;
                clock-names = "fclk";
                reg = <0x00 0x02840000 0x00 0x100>;
                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 281 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 281 2>;
                clock-names = "fclk";
                reg = <0x00 0x02850000 0x00 0x100>;
                interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 282 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 282 2>;
                clock-names = "fclk";
                reg = <0x00 0x02860000 0x00 0x100>;
                interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 283 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 283 2>;
                clock-names = "fclk";
                reg = <0x00 0x02870000 0x00 0x100>;
                interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 284 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 284 2>;
                clock-names = "fclk";
                reg = <0x00 0x02880000 0x00 0x100>;
                interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 285 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 285 2>;
                clock-names = "fclk";
                reg = <0x00 0x02890000 0x00 0x100>;
                interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 286 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 286 2>;
                clock-names = "fclk";
index 7cf21c99956e09c0cb40fc73e09853e51ef2139d..fccaabfb13482076d691e137ab3f5bce81056bb9 100644 (file)
                reg = <0x00 0x42300000 0x00 0x100>;
                interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 287 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 287 2>;
                clock-names = "fclk";
                reg = <0x00 0x40a00000 0x00 0x100>;
                interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <96000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 149 2>;
                clock-names = "fclk";
 
        fss: bus@47000000 {
                compatible = "simple-bus";
-               reg = <0x00 0x47000000 0x00 0x100>;
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges;
+               ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+                        <0x0 0x47034000 0x0 0x47040000 0x0 0x100>, /* HBMC Control */
+                        <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+                        <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>; /* HBMC/OSPI0 Memory */
 
                hbmc_mux: mux-controller@47000004 {
                        compatible = "reg-mux";
index c7eafbc862f96e58b009c7492d05b916797e7d49..0da785be80ff476a89ff5108db566c0f7099a6dc 100644 (file)
                reg = <0x00 0x02800000 0x00 0x100>;
                interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 146 0>;
                clock-names = "fclk";
                reg = <0x00 0x02810000 0x00 0x100>;
                interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 278 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 278 0>;
                clock-names = "fclk";
                reg = <0x00 0x02820000 0x00 0x100>;
                interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 279 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 279 0>;
                clock-names = "fclk";
                reg = <0x00 0x02830000 0x00 0x100>;
                interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 280 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 280 0>;
                clock-names = "fclk";
                reg = <0x00 0x02840000 0x00 0x100>;
                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 281 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 281 0>;
                clock-names = "fclk";
                reg = <0x00 0x02850000 0x00 0x100>;
                interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 282 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 282 0>;
                clock-names = "fclk";
                reg = <0x00 0x02860000 0x00 0x100>;
                interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 283 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 283 0>;
                clock-names = "fclk";
                reg = <0x00 0x02870000 0x00 0x100>;
                interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 284 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 284 0>;
                clock-names = "fclk";
                reg = <0x00 0x02880000 0x00 0x100>;
                interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 285 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 285 0>;
                clock-names = "fclk";
                reg = <0x00 0x02890000 0x00 0x100>;
                interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 286 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 286 0>;
                clock-names = "fclk";
index 4618b697fbc47c460f2739ea913247c41dfc9477..9349ae07c046e6acfa8843e325bd12fdb7ce6a75 100644 (file)
                reg = <0x00 0x42300000 0x00 0x100>;
                interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <48000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 287 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 287 0>;
                clock-names = "fclk";
                reg = <0x00 0x40a00000 0x00 0x100>;
                interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
                clock-frequency = <96000000>;
-               current-speed = <115200>;
                power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
                clocks = <&k3_clks 149 0>;
                clock-names = "fclk";
 
        fss: bus@47000000 {
                compatible = "simple-bus";
-               reg = <0x0 0x47000000 0x0 0x100>;
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges;
+               ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+                        <0x0 0x47034000 0x0 0x47034000 0x0 0x100>, /* HBMC Control */
+                        <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+                        <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+                        <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* HBMC/OSPI0 Memory */
+                        <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
 
                hbmc_mux: mux-controller@47000004 {
                        compatible = "reg-mux";
index b70c8615e3c15efa172af62b072420de16333a1b..9ed6949b40e9dfafdaf6861944b0b128b053a44f 100644 (file)
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02800000 0x00 0x200>;
                interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 146 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02810000 0x00 0x200>;
                interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 350 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 350 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02820000 0x00 0x200>;
                interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 351 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 351 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02830000 0x00 0x200>;
                interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 352 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 352 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02840000 0x00 0x200>;
                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 353 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 353 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02850000 0x00 0x200>;
                interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 354 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 354 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02860000 0x00 0x200>;
                interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 355 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 355 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02870000 0x00 0x200>;
                interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 356 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 356 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02880000 0x00 0x200>;
                interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 357 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 357 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02890000 0x00 0x200>;
                interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 358 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 358 TI_SCI_PD_EXCLUSIVE>;
                ti,clkbuf-sel = <0x7>;
                ti,trm-icp = <0x8>;
                dma-coherent;
-               /* Masking support for SDR104 capability */
-               sdhci-caps-mask = <0x00000003 0x00000000>;
                status = "disabled";
        };
 
index eaf7f709440e6e19f85dcb64324613bb09821aab..5ccb04c7c4624efff9e512fb87b90440a77de863 100644 (file)
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x42300000 0x00 0x200>;
                interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 359 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 359 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x40a00000 0x00 0x200>;
                interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 149 3>;
                clock-names = "fclk";
                power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
index be4502fe1c9d99c9e99e4f425652bb690be7d411..568e6a04619d82abf073a13ebf1cb57987227894 100644 (file)
                #size-cells = <2>;
                ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
                         <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+                        <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
                         <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
                         <0x00 0x0d800000 0x00 0x0d800000 0x00 0x00800000>, /* PCIe Core*/
                         <0x00 0x18000000 0x00 0x18000000 0x00 0x08000000>, /* PCIe1 DAT0 */
index cee3a8661d5e3c82e932590f78546a10227c5603..bf3c246d13d1f5fc09f72427a2aa84fdf0ef16c1 100644 (file)
 &cpsw_port1 {
        phy-mode = "rgmii-rxid";
        phy-handle = <&cpsw3g_phy0>;
-};
-
-&cpsw_port2 {
-       status = "disabled";
+       status = "okay";
 };
 
 &main_gpio1 {
 
 };
 
+&sdhci0 {
+       disable-wp;
+       bootph-all;
+       ti,driver-strength-ohm = <50>;
+       status = "okay";
+};
+
 &sdhci1 {
        /* SD/MMC */
        vmmc-supply = <&vdd_mmc1>;
        pinctrl-0 = <&main_mmc1_pins_default>;
        ti,driver-strength-ohm = <50>;
        disable-wp;
-       no-1-8-v;
        status = "okay";
        bootph-all;
 };
index 81fd7afac8c577a632175c206fe008ee393fad6e..d511b25d62e37024813f78c6cbac66407d0e398c 100644 (file)
        wkup_uart0_pins_default: wkup-uart0-default-pins {
                bootph-all;
                pinctrl-single,pins = <
-                       J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
-                       J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
+                       J784S4_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
+                       J784S4_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (K34) WKUP_UART0_TXD */
                >;
        };
 
        wkup_i2c0_pins_default: wkup-i2c0-default-pins {
                bootph-all;
                pinctrl-single,pins = <
-                       J721S2_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
-                       J721S2_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
+                       J784S4_WKUP_IOPAD(0x98, PIN_INPUT, 0) /* (N33) WKUP_I2C0_SCL */
+                       J784S4_WKUP_IOPAD(0x9c, PIN_INPUT, 0) /* (N35) WKUP_I2C0_SDA */
                >;
        };
 
index b67c37460a73d8033107ded849b3b445e49d7d35..6a4554c6c9c1305127e894cc150bbe3a465ba5d0 100644 (file)
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02800000 0x00 0x200>;
                interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 146 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02810000 0x00 0x200>;
                interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 388 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 388 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02820000 0x00 0x200>;
                interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 389 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 389 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02830000 0x00 0x200>;
                interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 390 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 390 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02840000 0x00 0x200>;
                interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 391 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 391 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02850000 0x00 0x200>;
                interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 392 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 392 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02860000 0x00 0x200>;
                interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 393 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 393 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02870000 0x00 0x200>;
                interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 394 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 394 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02880000 0x00 0x200>;
                interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 395 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 395 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x02890000 0x00 0x200>;
                interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 396 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 396 TI_SCI_PD_EXCLUSIVE>;
                ti,clkbuf-sel = <0x7>;
                ti,trm-icp = <0x8>;
                dma-coherent;
-               sdhci-caps-mask = <0x00000003 0x00000000>;
-               no-1-8-v;
                status = "disabled";
        };
 
index 77a8d99139ec15677c0cfc2cb6d4e919f489af00..2e18d91ae92f8e63ef651bb3e0d4757162457a88 100644 (file)
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x42300000 0x00 0x200>;
                interrupts = <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 397 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 397 TI_SCI_PD_EXCLUSIVE>;
                compatible = "ti,j721e-uart", "ti,am654-uart";
                reg = <0x00 0x40a00000 0x00 0x200>;
                interrupts = <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>;
-               current-speed = <115200>;
                clocks = <&k3_clks 149 0>;
                clock-names = "fclk";
                power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>;
 
        fss: bus@47000000 {
                compatible = "simple-bus";
-               reg = <0x00 0x47000000 0x00 0x100>;
                #address-cells = <2>;
                #size-cells = <2>;
-               ranges;
+               ranges = <0x0 0x47000000 0x0 0x47000000 0x0 0x100>, /* FSS Control */
+                        <0x0 0x47040000 0x0 0x47040000 0x0 0x100>, /* OSPI0 Control */
+                        <0x0 0x47050000 0x0 0x47050000 0x0 0x100>, /* OSPI1 Control */
+                        <0x5 0x00000000 0x5 0x00000000 0x1 0x0000000>, /* OSPI0 Memory */
+                        <0x7 0x00000000 0x7 0x00000000 0x1 0x0000000>; /* OSPI1 Memory */
 
                ospi0: spi@47040000 {
                        compatible = "ti,am654-ospi", "cdns,qspi-nor";
index 6e2e92ffe7452b8a8ed1c1ece3b451a6360dceec..da7368ed6b521dfd64241234837345e3555f2b67 100644 (file)
                #size-cells = <2>;
                ranges = <0x00 0x00100000 0x00 0x00100000 0x00 0x00020000>, /* ctrl mmr */
                         <0x00 0x00600000 0x00 0x00600000 0x00 0x00031100>, /* GPIO */
+                        <0x00 0x00700000 0x00 0x00700000 0x00 0x00001000>, /* ESM */
                         <0x00 0x01000000 0x00 0x01000000 0x00 0x0d000000>, /* Most peripherals */
                         <0x00 0x04210000 0x00 0x04210000 0x00 0x00010000>, /* VPU0 */
                         <0x00 0x04220000 0x00 0x04220000 0x00 0x00010000>, /* VPU1 */
index 25d20d8032305d1f922c3cbb28b9705bcd4b1e57..34d0e0be3fe61de5d45628bdb50660cde2df4538 100644 (file)
        };
 
        pmu {
-               compatible = "arm,armv8-pmuv3";
+               compatible = "arm,cortex-a53-pmu";
                interrupt-parent = <&gic>;
                interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
                             <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
index 2c30d617e18022dd3322895c868145e1fc71021a..d35150a979d4bba0a8ae4ffc01891ad268d7c405 100644 (file)
@@ -34,6 +34,7 @@ CONFIG_KEXEC=y
 CONFIG_KEXEC_FILE=y
 CONFIG_CRASH_DUMP=y
 CONFIG_ARCH_ACTIONS=y
+CONFIG_ARCH_AIROHA=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_APPLE=y
@@ -411,6 +412,7 @@ CONFIG_WCN36XX=m
 CONFIG_ATH11K=m
 CONFIG_ATH11K_AHB=m
 CONFIG_ATH11K_PCI=m
+CONFIG_ATH12K=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_SDIO=m
@@ -445,6 +447,7 @@ CONFIG_INPUT_TPS65219_PWRBUTTON=m
 CONFIG_INPUT_PWM_BEEPER=m
 CONFIG_INPUT_PWM_VIBRA=m
 CONFIG_INPUT_RK805_PWRKEY=m
+CONFIG_INPUT_DA9063_ONKEY=m
 CONFIG_INPUT_HISI_POWERKEY=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_SERIO_AMBAKMI=y
@@ -562,6 +565,7 @@ CONFIG_SPI_TEGRA114=m
 CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
 CONFIG_SPMI_MTK_PMIF=m
+CONFIG_PINCTRL_DA9062=m
 CONFIG_PINCTRL_MAX77620=y
 CONFIG_PINCTRL_RK805=m
 CONFIG_PINCTRL_SINGLE=y
@@ -727,6 +731,7 @@ CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_I2C=y
 CONFIG_MFD_AXP20X_RSB=y
+CONFIG_MFD_DA9062=m
 CONFIG_MFD_EXYNOS_LPASS=m
 CONFIG_MFD_HI6421_PMIC=y
 CONFIG_MFD_HI655X_PMIC=y
@@ -772,6 +777,7 @@ CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_QCOM_RPMH=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_QCOM_USB_VBUS=m
 CONFIG_REGULATOR_RAA215300=y
 CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_S2MPS11=y
@@ -854,6 +860,7 @@ CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_RCAR_DW_HDMI=m
 CONFIG_DRM_RCAR_MIPI_DSI=m
 CONFIG_DRM_RZG2L_MIPI_DSI=m
+CONFIG_DRM_RZG2L_DU=m
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_SUN6I_DSI=m
 CONFIG_DRM_SUN8I_DW_HDMI=m
@@ -865,7 +872,9 @@ CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
 CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
+CONFIG_DRM_PANEL_KHADAS_TS050=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
@@ -890,6 +899,7 @@ CONFIG_DRM_ANALOGIX_ANX7625=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_CDNS_MHDP8546=m
+CONFIG_DRM_IMX8MP_DW_HDMI_BRIDGE=m
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=m
 CONFIG_DRM_IMX_DCSS=m
@@ -907,6 +917,7 @@ CONFIG_DRM_MESON=m
 CONFIG_DRM_PL111=m
 CONFIG_DRM_LIMA=m
 CONFIG_DRM_PANFROST=m
+CONFIG_DRM_PANTHOR=m
 CONFIG_DRM_TIDSS=m
 CONFIG_DRM_POWERVR=m
 CONFIG_FB=y
@@ -949,6 +960,7 @@ CONFIG_SND_SOC_SM8250=m
 CONFIG_SND_SOC_SC8280XP=m
 CONFIG_SND_SOC_SC7180=m
 CONFIG_SND_SOC_SC7280=m
+CONFIG_SND_SOC_X1E80100=m
 CONFIG_SND_SOC_ROCKCHIP=m
 CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=m
 CONFIG_SND_SOC_ROCKCHIP_SPDIF=m
@@ -991,6 +1003,7 @@ CONFIG_SND_SOC_GTM601=m
 CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
 CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
 CONFIG_SND_SOC_PCM3168A_I2C=m
+CONFIG_SND_SOC_RK3308=m
 CONFIG_SND_SOC_RK817=m
 CONFIG_SND_SOC_RT5640=m
 CONFIG_SND_SOC_RT5659=m
@@ -1169,6 +1182,7 @@ CONFIG_RTC_DRV_RV8803=m
 CONFIG_RTC_DRV_S5M=y
 CONFIG_RTC_DRV_DS3232=y
 CONFIG_RTC_DRV_PCF2127=m
+CONFIG_RTC_DRV_DA9063=m
 CONFIG_RTC_DRV_EFI=y
 CONFIG_RTC_DRV_CROS_EC=y
 CONFIG_RTC_DRV_FSL_FTM_ALARM=m
@@ -1217,6 +1231,7 @@ CONFIG_STAGING=y
 CONFIG_STAGING_MEDIA=y
 CONFIG_VIDEO_MAX96712=m
 CONFIG_VIDEO_MESON_VDEC=m
+CONFIG_SND_BCM2835=m
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
@@ -1286,6 +1301,7 @@ CONFIG_QCM_DISPCC_2290=m
 CONFIG_QCS_GCC_404=y
 CONFIG_QDU_GCC_1000=y
 CONFIG_SC_CAMCC_8280XP=m
+CONFIG_SC_DISPCC_7280=m
 CONFIG_SC_DISPCC_8280XP=m
 CONFIG_SA_GCC_8775P=y
 CONFIG_SA_GPUCC_8775P=m
@@ -1293,6 +1309,7 @@ CONFIG_SC_GCC_7180=y
 CONFIG_SC_GCC_7280=y
 CONFIG_SC_GCC_8180X=y
 CONFIG_SC_GCC_8280XP=y
+CONFIG_SC_GPUCC_7280=m
 CONFIG_SC_GPUCC_8280XP=m
 CONFIG_SC_LPASSCC_8280XP=m
 CONFIG_SDM_CAMCC_845=m
@@ -1408,6 +1425,7 @@ CONFIG_ARCH_R9A07G044=y
 CONFIG_ARCH_R9A07G054=y
 CONFIG_ARCH_R9A08G045=y
 CONFIG_ARCH_R9A09G011=y
+CONFIG_ARCH_R9A09G057=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1473,6 +1491,7 @@ CONFIG_PWM_VISCONTI=m
 CONFIG_SL28CPLD_INTC=y
 CONFIG_QCOM_PDC=y
 CONFIG_QCOM_MPM=y
+CONFIG_RESET_GPIO=m
 CONFIG_RESET_IMX7=y
 CONFIG_RESET_QCOM_AOSS=y
 CONFIG_RESET_QCOM_PDC=m
@@ -1517,6 +1536,7 @@ CONFIG_PHY_ROCKCHIP_PCIE=m
 CONFIG_PHY_ROCKCHIP_SAMSUNG_HDPTX=m
 CONFIG_PHY_ROCKCHIP_SNPS_PCIE3=y
 CONFIG_PHY_ROCKCHIP_TYPEC=y
+CONFIG_PHY_ROCKCHIP_USBDP=m
 CONFIG_PHY_SAMSUNG_UFS=y
 CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_PHY_UNIPHIER_USB3=y
@@ -1585,6 +1605,7 @@ CONFIG_INTERCONNECT_QCOM_SC8180X=y
 CONFIG_INTERCONNECT_QCOM_SC8280XP=y
 CONFIG_INTERCONNECT_QCOM_SDM845=y
 CONFIG_INTERCONNECT_QCOM_SDX75=y
+CONFIG_INTERCONNECT_QCOM_SM6115=y
 CONFIG_INTERCONNECT_QCOM_SM8150=m
 CONFIG_INTERCONNECT_QCOM_SM8250=y
 CONFIG_INTERCONNECT_QCOM_SM8350=m
@@ -1599,6 +1620,7 @@ CONFIG_HTE_TEGRA194=y
 CONFIG_HTE_TEGRA194_TEST=m
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_FANOTIFY=y
@@ -1647,6 +1669,7 @@ CONFIG_CRYPTO_DEV_FSL_CAAM=m
 CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCOM_RNG=m
+CONFIG_CRYPTO_DEV_TEGRA=m
 CONFIG_CRYPTO_DEV_CCREE=m
 CONFIG_CRYPTO_DEV_HISI_SEC2=m
 CONFIG_CRYPTO_DEV_HISI_ZIP=m
index f48b8dab8b3d2fe175a02ddf3c81aa39dea5f16c..1d26bb5b02f4b592775dee6f964938f8ce4c866c 100644 (file)
@@ -338,12 +338,12 @@ int kvm_register_vgic_device(unsigned long type)
 int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
                       struct vgic_reg_attr *reg_attr)
 {
-       int cpuid;
+       int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
 
-       cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
-
-       reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
        reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
+       reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
+       if (!reg_attr->vcpu)
+               return -EINVAL;
 
        return 0;
 }
index 122021f9bdfc87c3c9634d6801edad7845b9f96e..13eac43c632dfe793912ba310f7449d59e3bd9ed 100644 (file)
@@ -1844,15 +1844,15 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
 
        emit_call(enter_prog, ctx);
 
+       /* save return value to callee saved register x20 */
+       emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
+
        /* if (__bpf_prog_enter(prog) == 0)
         *         goto skip_exec_of_prog;
         */
        branch = ctx->image + ctx->idx;
        emit(A64_NOP, ctx);
 
-       /* save return value to callee saved register x20 */
-       emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
-
        emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx);
        if (!p->jited)
                emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx);
index d3ac36751ad1f6ededf86a2d0553883898140989..5479707eb5d10df1e083c9c7c547c266b64f4232 100644 (file)
@@ -37,6 +37,7 @@ config CSKY
        select ARCH_INLINE_SPIN_UNLOCK_BH if !PREEMPTION
        select ARCH_INLINE_SPIN_UNLOCK_IRQ if !PREEMPTION
        select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
+       select ARCH_NEED_CMPXCHG_1_EMU
        select ARCH_WANT_FRAME_POINTERS if !CPU_CK610 && $(cc-option,-mbacktrace)
        select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
        select COMMON_CLK
index 916043b845f14248467d276db216d8e29a41e01d..db6dda47184e4ba75927569ae0e0e88247879d83 100644 (file)
@@ -6,6 +6,7 @@
 #ifdef CONFIG_SMP
 #include <linux/bug.h>
 #include <asm/barrier.h>
+#include <linux/cmpxchg-emu.h>
 
 #define __xchg_relaxed(new, ptr, size)                         \
 ({                                                             \
@@ -61,6 +62,9 @@
        __typeof__(old) __old = (old);                          \
        __typeof__(*(ptr)) __ret;                               \
        switch (size) {                                         \
+       case 1:                                                 \
+               __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+               break;                                          \
        case 4:                                                 \
                asm volatile (                                  \
                "1:     ldex.w          %0, (%3) \n"            \
@@ -91,6 +95,9 @@
        __typeof__(old) __old = (old);                          \
        __typeof__(*(ptr)) __ret;                               \
        switch (size) {                                         \
+       case 1:                                                 \
+               __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+               break;                                          \
        case 4:                                                 \
                asm volatile (                                  \
                "1:     ldex.w          %0, (%3) \n"            \
        __typeof__(old) __old = (old);                          \
        __typeof__(*(ptr)) __ret;                               \
        switch (size) {                                         \
+       case 1:                                                 \
+               __ret = (__typeof__(*(ptr)))cmpxchg_emu_u8((volatile u8 *)__ptr, (uintptr_t)__old, (uintptr_t)__new); \
+               break;                                          \
        case 4:                                                 \
                asm volatile (                                  \
                RELEASE_FENCE                                   \
index c1d776bb16b4edeeee71066e243173aef1e51b5b..bf0a0f1189eb21795f826d3d4efa2416e5bc880f 100644 (file)
@@ -56,26 +56,24 @@ __arch_xchg(unsigned long x, volatile void *ptr, int size)
 /* bug catcher for when unsupported size is used - won't link */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-/* __cmpxchg_u32/u64 defined in arch/parisc/lib/bitops.c */
-extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old,
-                                  unsigned int new_);
-extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_);
+/* __cmpxchg_u... defined in arch/parisc/lib/bitops.c */
 extern u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new_);
+extern u16 __cmpxchg_u16(volatile u16 *ptr, u16 old, u16 new_);
+extern u32 __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_);
 
 /* don't worry...optimizer will get rid of most of this */
 static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
 {
-       switch (size) {
+       return
 #ifdef CONFIG_64BIT
-       case 8: return __cmpxchg_u64((u64 *)ptr, old, new_);
+               size == 8 ? __cmpxchg_u64(ptr, old, new_) :
 #endif
-       case 4: return __cmpxchg_u32((unsigned int *)ptr,
-                                    (unsigned int)old, (unsigned int)new_);
-       case 1: return __cmpxchg_u8((u8 *)ptr, old & 0xff, new_ & 0xff);
-       }
-       __cmpxchg_called_with_bad_pointer();
-       return old;
+               size == 4 ? __cmpxchg_u32(ptr, old, new_) :
+               size == 2 ? __cmpxchg_u16(ptr, old, new_) :
+               size == 1 ? __cmpxchg_u8(ptr, old, new_) :
+                       (__cmpxchg_called_with_bad_pointer(), old);
 }
 
 #define arch_cmpxchg(ptr, o, n)                                                 \
index 6f0c92e8149d828afc68824e9231703ff99f2bee..c1587aa35beb6e5f855f006653a5cb5b99d8b8f9 100644 (file)
@@ -22,6 +22,8 @@ EXPORT_SYMBOL(memset);
 #include <linux/atomic.h>
 EXPORT_SYMBOL(__xchg8);
 EXPORT_SYMBOL(__xchg32);
+EXPORT_SYMBOL(__cmpxchg_u8);
+EXPORT_SYMBOL(__cmpxchg_u16);
 EXPORT_SYMBOL(__cmpxchg_u32);
 EXPORT_SYMBOL(__cmpxchg_u64);
 #ifdef CONFIG_SMP
index 36a3141990746798444597e3b4e864dd9db54330..9df81005064278c378222fcca7919fb2ed4bb28a 100644 (file)
@@ -56,38 +56,20 @@ unsigned long notrace __xchg8(char x, volatile char *ptr)
 }
 
 
-u64 notrace __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new)
-{
-       unsigned long flags;
-       u64 prev;
-
-       _atomic_spin_lock_irqsave(ptr, flags);
-       if ((prev = *ptr) == old)
-               *ptr = new;
-       _atomic_spin_unlock_irqrestore(ptr, flags);
-       return prev;
-}
-
-unsigned long notrace __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
-{
-       unsigned long flags;
-       unsigned int prev;
-
-       _atomic_spin_lock_irqsave(ptr, flags);
-       if ((prev = *ptr) == old)
-               *ptr = new;
-       _atomic_spin_unlock_irqrestore(ptr, flags);
-       return (unsigned long)prev;
-}
-
-u8 notrace __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new)
-{
-       unsigned long flags;
-       u8 prev;
-
-       _atomic_spin_lock_irqsave(ptr, flags);
-       if ((prev = *ptr) == old)
-               *ptr = new;
-       _atomic_spin_unlock_irqrestore(ptr, flags);
-       return prev;
-}
+#define CMPXCHG(T)                                             \
+       T notrace __cmpxchg_##T(volatile T *ptr, T old, T new)  \
+       {                                                       \
+               unsigned long flags;                            \
+               T prev;                                         \
+                                                               \
+               _atomic_spin_lock_irqsave(ptr, flags);          \
+               if ((prev = *ptr) == old)                       \
+                       *ptr = new;                             \
+               _atomic_spin_unlock_irqrestore(ptr, flags);     \
+               return prev;                                    \
+       }
+
+CMPXCHG(u64)
+CMPXCHG(u32)
+CMPXCHG(u16)
+CMPXCHG(u8)
index 23b77027c91637d0ef05e9952ebc1e72f7c24aa3..7a84069759b032dc61c2545773550417bf177d64 100644 (file)
@@ -44,9 +44,8 @@
 #define PLPKS_MAX_DATA_SIZE            4000
 
 // Timeouts for PLPKS operations
-#define PLPKS_MAX_TIMEOUT              5000 // msec
-#define PLPKS_FLUSH_SLEEP              10 // msec
-#define PLPKS_FLUSH_SLEEP_RANGE                400
+#define PLPKS_MAX_TIMEOUT              (5 * USEC_PER_SEC)
+#define PLPKS_FLUSH_SLEEP              10000 // usec
 
 struct plpks_var {
        char *component;
index e8c4129697b142ba48490481ee38793086e8425a..b1e6d275cda9ebaa7fa4659905691348d17faa75 100644 (file)
@@ -786,8 +786,16 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
         * parent bus. During reboot, there will be ibm,dma-window property to
         * define DMA window. For kdump, there will at least be default window or DDW
         * or both.
+        * There is an exception to the above. In case the PE goes into frozen
+        * state, firmware may not provide ibm,dma-window property at the time
+        * of LPAR boot up.
         */
 
+       if (!pdn) {
+               pr_debug("  no ibm,dma-window property !\n");
+               return;
+       }
+
        ppci = PCI_DN(pdn);
 
        pr_debug("  parent is %pOF, iommu_table: 0x%p\n",
index febe18f251d0cfb360a6330e4d0932e6941ae75e..4a595493d28ae3b808db8394e02c2b85b600b417 100644 (file)
@@ -415,8 +415,7 @@ static int plpks_confirm_object_flushed(struct label *label,
                        break;
                }
 
-               usleep_range(PLPKS_FLUSH_SLEEP,
-                            PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE);
+               fsleep(PLPKS_FLUSH_SLEEP);
                timeout = timeout + PLPKS_FLUSH_SLEEP;
        } while (timeout < PLPKS_MAX_TIMEOUT);
 
@@ -464,9 +463,10 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags)
 
                continuetoken = retbuf[0];
                if (pseries_status_to_err(rc) == -EBUSY) {
-                       int delay_ms = get_longbusy_msecs(rc);
-                       mdelay(delay_ms);
-                       timeout += delay_ms;
+                       int delay_us = get_longbusy_msecs(rc) * 1000;
+
+                       fsleep(delay_us);
+                       timeout += delay_us;
                }
                rc = pseries_status_to_err(rc);
        } while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT);
index 910ba8837add866f622fba84f7c0c3535ee175e6..2acc7d876e1fb6aa5dc14ad3c3150f587ba1edea 100644 (file)
@@ -82,14 +82,14 @@ config ERRATA_THEAD
 
          Otherwise, please say "N" here to avoid unnecessary overhead.
 
-config ERRATA_THEAD_PBMT
-       bool "Apply T-Head memory type errata"
+config ERRATA_THEAD_MAE
+       bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
        depends on ERRATA_THEAD && 64BIT && MMU
        select RISCV_ALTERNATIVE_EARLY
        default y
        help
-         This will apply the memory type errata to handle the non-standard
-         memory type bits in page-table-entries on T-Head SoCs.
+         This will apply the memory attribute extension errata to handle the
+         non-standard PTE utilization on T-Head SoCs (XTheadMae).
 
          If you don't know what to do here, say "Y".
 
index 623de5f8a2089848372c9ccd314b66db4f8236d4..f51bb24bc84c6e475e04c2b430cde39c9c9f546d 100644 (file)
@@ -1,12 +1,12 @@
 menu "SoC selection"
 
 config ARCH_MICROCHIP_POLARFIRE
-       def_bool SOC_MICROCHIP_POLARFIRE
+       def_bool ARCH_MICROCHIP
 
-config SOC_MICROCHIP_POLARFIRE
-       bool "Microchip PolarFire SoCs"
+config ARCH_MICROCHIP
+       bool "Microchip SoCs"
        help
-         This enables support for Microchip PolarFire SoC platforms.
+         This enables support for Microchip SoC platforms.
 
 config ARCH_RENESAS
        bool "Renesas RISC-V SoCs"
@@ -14,9 +14,6 @@ config ARCH_RENESAS
          This enables support for the RISC-V based Renesas SoCs.
 
 config ARCH_SIFIVE
-       def_bool SOC_SIFIVE
-
-config SOC_SIFIVE
        bool "SiFive SoCs"
        select ERRATA_SIFIVE if !XIP_KERNEL
        help
@@ -55,9 +52,6 @@ config ARCH_THEAD
          This enables support for the RISC-V based T-HEAD SoCs.
 
 config ARCH_VIRT
-       def_bool SOC_VIRT
-
-config SOC_VIRT
        bool "QEMU Virt Machine"
        select CLINT_TIMER if RISCV_M_MODE
        select POWER_RESET
@@ -72,11 +66,13 @@ config SOC_VIRT
          This enables support for QEMU Virt Machine.
 
 config ARCH_CANAAN
-       def_bool SOC_CANAAN
+       bool "Canaan Kendryte SoC"
+       help
+         This enables support for Canaan Kendryte series SoC platform hardware.
 
-config SOC_CANAAN
+config SOC_CANAAN_K210
        bool "Canaan Kendryte K210 SoC"
-       depends on !MMU
+       depends on !MMU && ARCH_CANAAN
        select CLINT_TIMER if RISCV_M_MODE
        select ARCH_HAS_RESET_CONTROLLER
        select PINCTRL
index 5b3115a198522684cbcba474953e07d4e76e9ff5..1e002d8003c56dee8f26a1fd5f0c2b38b9f73391 100644 (file)
@@ -154,7 +154,7 @@ vdso-install-y                      += arch/riscv/kernel/vdso/vdso.so.dbg
 vdso-install-$(CONFIG_COMPAT)  += arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg
 
 ifneq ($(CONFIG_XIP_KERNEL),y)
-ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_ARCH_CANAAN),yy)
+ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN_K210),yy)
 KBUILD_IMAGE := $(boot)/loader.bin
 else
 ifeq ($(CONFIG_EFI_ZBOOT),)
index f35324b9173cde4985e0eba9dc807c4bcfc7f534..e0ddf8f602c79bc87253aff10925ad7edd08bf9c 100644 (file)
        dma-noncoherent;
        interrupt-parent = <&plic>;
 
+       irqc: interrupt-controller@110a0000 {
+               compatible = "renesas,r9a07g043f-irqc";
+               reg = <0 0x110a0000 0 0x20000>;
+               #interrupt-cells = <2>;
+               #address-cells = <0>;
+               interrupt-controller;
+               interrupts = <32 IRQ_TYPE_LEVEL_HIGH>,
+                            <33 IRQ_TYPE_LEVEL_HIGH>,
+                            <34 IRQ_TYPE_LEVEL_HIGH>,
+                            <35 IRQ_TYPE_LEVEL_HIGH>,
+                            <36 IRQ_TYPE_LEVEL_HIGH>,
+                            <37 IRQ_TYPE_LEVEL_HIGH>,
+                            <38 IRQ_TYPE_LEVEL_HIGH>,
+                            <39 IRQ_TYPE_LEVEL_HIGH>,
+                            <40 IRQ_TYPE_LEVEL_HIGH>,
+                            <476 IRQ_TYPE_LEVEL_HIGH>,
+                            <477 IRQ_TYPE_LEVEL_HIGH>,
+                            <478 IRQ_TYPE_LEVEL_HIGH>,
+                            <479 IRQ_TYPE_LEVEL_HIGH>,
+                            <480 IRQ_TYPE_LEVEL_HIGH>,
+                            <481 IRQ_TYPE_LEVEL_HIGH>,
+                            <482 IRQ_TYPE_LEVEL_HIGH>,
+                            <483 IRQ_TYPE_LEVEL_HIGH>,
+                            <484 IRQ_TYPE_LEVEL_HIGH>,
+                            <485 IRQ_TYPE_LEVEL_HIGH>,
+                            <486 IRQ_TYPE_LEVEL_HIGH>,
+                            <487 IRQ_TYPE_LEVEL_HIGH>,
+                            <488 IRQ_TYPE_LEVEL_HIGH>,
+                            <489 IRQ_TYPE_LEVEL_HIGH>,
+                            <490 IRQ_TYPE_LEVEL_HIGH>,
+                            <491 IRQ_TYPE_LEVEL_HIGH>,
+                            <492 IRQ_TYPE_LEVEL_HIGH>,
+                            <493 IRQ_TYPE_LEVEL_HIGH>,
+                            <494 IRQ_TYPE_LEVEL_HIGH>,
+                            <495 IRQ_TYPE_LEVEL_HIGH>,
+                            <496 IRQ_TYPE_LEVEL_HIGH>,
+                            <497 IRQ_TYPE_LEVEL_HIGH>,
+                            <498 IRQ_TYPE_LEVEL_HIGH>,
+                            <499 IRQ_TYPE_LEVEL_HIGH>,
+                            <500 IRQ_TYPE_LEVEL_HIGH>,
+                            <501 IRQ_TYPE_LEVEL_HIGH>,
+                            <502 IRQ_TYPE_LEVEL_HIGH>,
+                            <503 IRQ_TYPE_LEVEL_HIGH>,
+                            <504 IRQ_TYPE_LEVEL_HIGH>,
+                            <505 IRQ_TYPE_LEVEL_HIGH>,
+                            <506 IRQ_TYPE_LEVEL_HIGH>,
+                            <507 IRQ_TYPE_LEVEL_HIGH>,
+                            <57 IRQ_TYPE_LEVEL_HIGH>,
+                            <66 IRQ_TYPE_EDGE_RISING>,
+                            <67 IRQ_TYPE_EDGE_RISING>,
+                            <68 IRQ_TYPE_EDGE_RISING>,
+                            <69 IRQ_TYPE_EDGE_RISING>,
+                            <70 IRQ_TYPE_EDGE_RISING>,
+                            <71 IRQ_TYPE_EDGE_RISING>;
+               interrupt-names = "nmi",
+                                 "irq0", "irq1", "irq2", "irq3",
+                                 "irq4", "irq5", "irq6", "irq7",
+                                 "tint0", "tint1", "tint2", "tint3",
+                                 "tint4", "tint5", "tint6", "tint7",
+                                 "tint8", "tint9", "tint10", "tint11",
+                                 "tint12", "tint13", "tint14", "tint15",
+                                 "tint16", "tint17", "tint18", "tint19",
+                                 "tint20", "tint21", "tint22", "tint23",
+                                 "tint24", "tint25", "tint26", "tint27",
+                                 "tint28", "tint29", "tint30", "tint31",
+                                 "bus-err", "ec7tie1-0", "ec7tie2-0",
+                                 "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+                                 "ec7tiovf-1";
+               clocks = <&cpg CPG_MOD R9A07G043_IAX45_CLK>,
+                        <&cpg CPG_MOD R9A07G043_IAX45_PCLK>;
+               clock-names = "clk", "pclk";
+               power-domains = <&cpg>;
+               resets = <&cpg R9A07G043_IAX45_RESETN>;
+       };
+
        plic: interrupt-controller@12c00000 {
                compatible = "renesas,r9a07g043-plic", "andestech,nceplic100";
                #interrupt-cells = <2>;
index 433ab5c6a626c30fe4d5c751d427629fbfbd87b9..5e808242649ec1768a6262a326be000a4c3d2f98 100644 (file)
@@ -6,19 +6,3 @@
  */
 
 #include <arm64/renesas/rzg2ul-smarc-som.dtsi>
-
-#if (!SW_ET0_EN_N)
-&eth0 {
-       phy0: ethernet-phy@7 {
-               /delete-property/ interrupt-parent;
-               /delete-property/ interrupts;
-       };
-};
-#endif
-
-&eth1 {
-       phy1: ethernet-phy@7 {
-               /delete-property/ interrupt-parent;
-               /delete-property/ interrupts;
-       };
-};
index 3af9e34b3bc75d19760064ffc82179cfc715bd71..cd013588adc0e3adcb1df8a9dce2ae714d11f131 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       memory@80000000 {
-               device_type = "memory";
-               reg = <0x80000000 0x3f40000>;
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               coprocessor_rtos: region@83f40000 {
+                       reg = <0x83f40000 0xc0000>;
+                       no-map;
+               };
        };
 };
 
        clock-frequency = <25000000>;
 };
 
+&sdhci0 {
+       status = "okay";
+       bus-width = <4>;
+       no-1-8-v;
+       no-mmc;
+       no-sdio;
+};
+
 &uart0 {
        status = "okay";
 };
index 165e9e320a8c72d7f56ecb61fd86e7d58c8c4333..ec9530972ae2bbb6b319c4db694c8a5633c0bed9 100644 (file)
@@ -7,6 +7,11 @@
 
 / {
        compatible = "sophgo,cv1800b";
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x4000000>;
+       };
 };
 
 &plic {
@@ -16,3 +21,7 @@
 &clint {
        compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
 };
+
+&clk {
+       compatible = "sophgo,cv1800-clk";
+};
index 3e7a942f5c1a5ac988291b0b2224ffc750ce86c7..7fa4c1e2d1da45ac705fcc0d4dd289e31a9b2a15 100644 (file)
@@ -22,3 +22,7 @@
 &clint {
        compatible = "sophgo,cv1812h-clint", "thead,c900-clint";
 };
+
+&clk {
+       compatible = "sophgo,cv1810-clk";
+};
index 2d6f4a4b1e58b4b56ac49c051af7fbc5bf9c4d12..891932ae470f3421ee6a9c0ee2660603f9904c69 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com>
  */
 
+#include <dt-bindings/clock/sophgo,cv1800.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 
 / {
                dma-noncoherent;
                ranges;
 
+               clk: clock-controller@3002000 {
+                       reg = <0x03002000 0x1000>;
+                       clocks = <&osc>;
+                       #clock-cells = <1>;
+               };
+
                gpio0: gpio@3020000 {
                        compatible = "snps,dw-apb-gpio";
                        reg = <0x3020000 0x1000>;
                        };
                };
 
+               i2c0: i2c@4000000 {
+                       compatible = "snps,designware-i2c";
+                       reg = <0x04000000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C0>;
+                       clock-names = "ref", "pclk";
+                       interrupts = <49 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               i2c1: i2c@4010000 {
+                       compatible = "snps,designware-i2c";
+                       reg = <0x04010000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C1>;
+                       clock-names = "ref", "pclk";
+                       interrupts = <50 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@4020000 {
+                       compatible = "snps,designware-i2c";
+                       reg = <0x04020000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C2>;
+                       clock-names = "ref", "pclk";
+                       interrupts = <51 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               i2c3: i2c@4030000 {
+                       compatible = "snps,designware-i2c";
+                       reg = <0x04030000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C3>;
+                       clock-names = "ref", "pclk";
+                       interrupts = <52 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@4040000 {
+                       compatible = "snps,designware-i2c";
+                       reg = <0x04040000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_I2C>, <&clk CLK_APB_I2C4>;
+                       clock-names = "ref", "pclk";
+                       interrupts = <53 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
                uart0: serial@4140000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x04140000 0x100>;
                        interrupts = <44 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&osc>;
+                       clocks = <&clk CLK_UART0>, <&clk CLK_APB_UART0>;
+                       clock-names = "baudclk", "apb_pclk";
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        status = "disabled";
                        compatible = "snps,dw-apb-uart";
                        reg = <0x04150000 0x100>;
                        interrupts = <45 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&osc>;
+                       clocks = <&clk CLK_UART1>, <&clk CLK_APB_UART1>;
+                       clock-names = "baudclk", "apb_pclk";
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        status = "disabled";
                        compatible = "snps,dw-apb-uart";
                        reg = <0x04160000 0x100>;
                        interrupts = <46 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&osc>;
+                       clocks = <&clk CLK_UART2>, <&clk CLK_APB_UART2>;
+                       clock-names = "baudclk", "apb_pclk";
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        status = "disabled";
                        compatible = "snps,dw-apb-uart";
                        reg = <0x04170000 0x100>;
                        interrupts = <47 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&osc>;
+                       clocks = <&clk CLK_UART3>, <&clk CLK_APB_UART3>;
+                       clock-names = "baudclk", "apb_pclk";
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        status = "disabled";
                };
 
+               spi0: spi@4180000 {
+                       compatible = "snps,dw-apb-ssi";
+                       reg = <0x04180000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI0>;
+                       clock-names = "ssi_clk", "pclk";
+                       interrupts = <54 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               spi1: spi@4190000 {
+                       compatible = "snps,dw-apb-ssi";
+                       reg = <0x04190000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI1>;
+                       clock-names = "ssi_clk", "pclk";
+                       interrupts = <55 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               spi2: spi@41a0000 {
+                       compatible = "snps,dw-apb-ssi";
+                       reg = <0x041a0000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI2>;
+                       clock-names = "ssi_clk", "pclk";
+                       interrupts = <56 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
+               spi3: spi@41b0000 {
+                       compatible = "snps,dw-apb-ssi";
+                       reg = <0x041b0000 0x10000>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       clocks = <&clk CLK_SPI>, <&clk CLK_APB_SPI3>;
+                       clock-names = "ssi_clk", "pclk";
+                       interrupts = <57 IRQ_TYPE_LEVEL_HIGH>;
+                       status = "disabled";
+               };
+
                uart4: serial@41c0000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x041c0000 0x100>;
                        interrupts = <48 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&osc>;
+                       clocks = <&clk CLK_UART4>, <&clk CLK_APB_UART4>;
+                       clock-names = "baudclk", "apb_pclk";
                        reg-shift = <2>;
                        reg-io-width = <4>;
                        status = "disabled";
                };
 
+               sdhci0: mmc@4310000 {
+                       compatible = "sophgo,cv1800b-dwcmshc";
+                       reg = <0x4310000 0x1000>;
+                       interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk CLK_AXI4_SD0>,
+                                <&clk CLK_SD0>;
+                       clock-names = "core", "bus";
+                       status = "disabled";
+               };
+
                plic: interrupt-controller@70000000 {
                        reg = <0x70000000 0x4000000>;
                        interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
index fc0ec2ee13bc22c842e7ce4025e92e05599b5e1c..3cae018f9315e6a93e4c660934ea4fa3bd436c4b 100644 (file)
@@ -25,14 +25,15 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
 CONFIG_PROFILING=y
-CONFIG_SOC_MICROCHIP_POLARFIRE=y
+CONFIG_ARCH_MICROCHIP=y
 CONFIG_ARCH_RENESAS=y
-CONFIG_SOC_SIFIVE=y
+CONFIG_ARCH_SIFIVE=y
 CONFIG_ARCH_SOPHGO=y
 CONFIG_SOC_STARFIVE=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_THEAD=y
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
+CONFIG_ARCH_CANAAN=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
 CONFIG_PM=y
index 7e75200543f453eadeec1bce6214d6a9d9e9a325..2552e78074a369d5f8a3a5e975b8cc9535922377 100644 (file)
@@ -27,7 +27,8 @@ CONFIG_EXPERT=y
 CONFIG_SLUB=y
 CONFIG_SLUB_TINY=y
 # CONFIG_MMU is not set
-CONFIG_SOC_CANAAN=y
+CONFIG_ARCH_CANAAN=y
+CONFIG_SOC_CANAAN_K210=y
 CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
index 0ba353e9ca71eebc91fbcb19dcda95d66613459a..8f67fb8305853d2182cf56625ebccee3440d5b45 100644 (file)
@@ -19,7 +19,8 @@ CONFIG_EXPERT=y
 CONFIG_SLUB=y
 CONFIG_SLUB_TINY=y
 # CONFIG_MMU is not set
-CONFIG_SOC_CANAAN=y
+CONFIG_ARCH_CANAAN=y
+CONFIG_SOC_CANAAN_K210=y
 CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
index b794e2f8144e665dd26dc05cc2b56908b46262b6..de8143d1f7382ae2c7073d5f7c35273aab3d1591 100644 (file)
@@ -24,7 +24,7 @@ CONFIG_EXPERT=y
 CONFIG_SLUB=y
 CONFIG_SLUB_TINY=y
 # CONFIG_MMU is not set
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
 CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
index b1c410bbc1aece3c1fe0bea8cbd68271c8c0e29a..bf6a0a6318ee307085c3cc04c4056a0b63a000e9 100644 (file)
 #include <asm/patch.h>
 #include <asm/vendorid_list.h>
 
-static bool errata_probe_pbmt(unsigned int stage,
-                             unsigned long arch_id, unsigned long impid)
+#define CSR_TH_SXSTATUS                0x5c0
+#define SXSTATUS_MAEE          _AC(0x200000, UL)
+
+static bool errata_probe_mae(unsigned int stage,
+                            unsigned long arch_id, unsigned long impid)
 {
-       if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT))
+       if (!IS_ENABLED(CONFIG_ERRATA_THEAD_MAE))
                return false;
 
        if (arch_id != 0 || impid != 0)
                return false;
 
-       if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
-           stage == RISCV_ALTERNATIVES_MODULE)
-               return true;
+       if (stage != RISCV_ALTERNATIVES_EARLY_BOOT &&
+           stage != RISCV_ALTERNATIVES_MODULE)
+               return false;
+
+       if (!(csr_read(CSR_TH_SXSTATUS) & SXSTATUS_MAEE))
+               return false;
 
-       return false;
+       return true;
 }
 
 /*
@@ -140,8 +146,8 @@ static u32 thead_errata_probe(unsigned int stage,
 {
        u32 cpu_req_errata = 0;
 
-       if (errata_probe_pbmt(stage, archid, impid))
-               cpu_req_errata |= BIT(ERRATA_THEAD_PBMT);
+       if (errata_probe_mae(stage, archid, impid))
+               cpu_req_errata |= BIT(ERRATA_THEAD_MAE);
 
        errata_probe_cmo(stage, archid, impid);
 
index 1f2dbfb8a8bfc8c9f5d46b9129c26756941c4918..efd851e1b48321e1f098008ce8fe7755ab49339d 100644 (file)
@@ -23,7 +23,7 @@
 #endif
 
 #ifdef CONFIG_ERRATA_THEAD
-#define        ERRATA_THEAD_PBMT 0
+#define        ERRATA_THEAD_MAE 0
 #define        ERRATA_THEAD_PMU 1
 #define        ERRATA_THEAD_NUMBER 2
 #endif
@@ -53,20 +53,20 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID,    \
  * in the default case.
  */
 #define ALT_SVPBMT_SHIFT 61
-#define ALT_THEAD_PBMT_SHIFT 59
+#define ALT_THEAD_MAE_SHIFT 59
 #define ALT_SVPBMT(_val, prot)                                         \
 asm(ALTERNATIVE_2("li %0, 0\t\nnop",                                   \
                  "li %0, %1\t\nslli %0,%0,%3", 0,                      \
                        RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,  \
                  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,        \
-                       ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)    \
+                       ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)      \
                : "=r"(_val)                                            \
                : "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),               \
-                 "I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT),            \
+                 "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT),             \
                  "I"(ALT_SVPBMT_SHIFT),                                \
-                 "I"(ALT_THEAD_PBMT_SHIFT))
+                 "I"(ALT_THEAD_MAE_SHIFT))
 
-#ifdef CONFIG_ERRATA_THEAD_PBMT
+#ifdef CONFIG_ERRATA_THEAD_MAE
 /*
  * IO/NOCACHE memory types are handled together with svpbmt,
  * so on T-Head chips, check if no other memory type is set,
@@ -83,11 +83,11 @@ asm volatile(ALTERNATIVE(                                           \
        "slli    t3, t3, %3\n\t"                                        \
        "or      %0, %0, t3\n\t"                                        \
        "2:",  THEAD_VENDOR_ID,                                         \
-               ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)            \
+               ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)              \
        : "+r"(_val)                                                    \
-       : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT),              \
-         "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT),                 \
-         "I"(ALT_THEAD_PBMT_SHIFT)                                     \
+       : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT),               \
+         "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT),                  \
+         "I"(ALT_THEAD_MAE_SHIFT)                                      \
        : "t3")
 #else
 #define ALT_THEAD_PMA(_val)
index 2947423b5082e9b7f69b25a347685af499258161..115ac98b8d729da4e8f07f0f8f44e27438be107f 100644 (file)
@@ -89,7 +89,7 @@ typedef struct page *pgtable_t;
 #define PTE_FMT "%08lx"
 #endif
 
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) && defined(CONFIG_MMU)
 /*
  * We override this value as its generic definition uses __pa too early in
  * the boot process (before kernel_map.va_pa_offset is set).
index 9f8ea0e33eb10424c5a05eb55849eacce627c3c3..6afd6bb4882eb28d1f1e96e451c7c92c20a6d2cc 100644 (file)
@@ -896,7 +896,7 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
 #define PAGE_SHARED            __pgprot(0)
 #define PAGE_KERNEL            __pgprot(0)
 #define swapper_pg_dir         NULL
-#define TASK_SIZE              0xffffffffUL
+#define TASK_SIZE              _AC(-1, UL)
 #define VMALLOC_START          _AC(0, UL)
 #define VMALLOC_END            TASK_SIZE
 
index 9f2a8e3ff2048e78201e188a5fc832a67429a06c..2902f68dc913aa620996da70d9b9bad39a133c2c 100644 (file)
@@ -54,7 +54,7 @@ struct riscv_hwprobe {
 #define                RISCV_HWPROBE_EXT_ZFHMIN        (1 << 28)
 #define                RISCV_HWPROBE_EXT_ZIHINTNTL     (1 << 29)
 #define                RISCV_HWPROBE_EXT_ZVFH          (1 << 30)
-#define                RISCV_HWPROBE_EXT_ZVFHMIN       (1 << 31)
+#define                RISCV_HWPROBE_EXT_ZVFHMIN       (1ULL << 31)
 #define                RISCV_HWPROBE_EXT_ZFA           (1ULL << 32)
 #define                RISCV_HWPROBE_EXT_ZTSO          (1ULL << 33)
 #define                RISCV_HWPROBE_EXT_ZACAS         (1ULL << 34)
index fe8e159394d8eeeeab34f83ae97ffadbec979b77..9687618432031fec77907d1c15fad0b9a3cc4c0a 100644 (file)
@@ -231,7 +231,7 @@ static void __init setup_bootmem(void)
         * In 64-bit, any use of __va/__pa before this point is wrong as we
         * did not know the start of DRAM before.
         */
-       if (IS_ENABLED(CONFIG_64BIT))
+       if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU))
                kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
 
        /*
index 1adf2f39ce59cbb691b7f89ae9fc7a5127642ca4..ec9d692838fca54ee445d10ab3d862130338cd3b 100644 (file)
@@ -722,6 +722,9 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
        if (ret)
                return ret;
 
+       /* store prog start time */
+       emit_mv(RV_REG_S1, RV_REG_A0, ctx);
+
        /* if (__bpf_prog_enter(prog) == 0)
         *      goto skip_exec_of_prog;
         */
@@ -729,9 +732,6 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
        /* nop reserved for conditional jump */
        emit(rv_nop(), ctx);
 
-       /* store prog start time */
-       emit_mv(RV_REG_S1, RV_REG_A0, ctx);
-
        /* arg1: &args_off */
        emit_addi(RV_REG_A0, RV_REG_FP, -args_off, ctx);
        if (!p->jited)
index 8f01ada6845e36086d85c32a076c8057208e498c..7e7fe89c9b253f76523c14875ebcccc1b47e9215 100644 (file)
@@ -17,6 +17,9 @@ config ARCH_HAS_ILOG2_U32
 config ARCH_HAS_ILOG2_U64
        def_bool n
 
+config ARCH_PROC_KCORE_TEXT
+       def_bool y
+
 config GENERIC_HWEIGHT
        def_bool y
 
@@ -552,7 +555,7 @@ config EXPOLINE
          If unsure, say N.
 
 config EXPOLINE_EXTERN
-       def_bool n
+       def_bool y if EXPOLINE
        depends on EXPOLINE
        depends on CC_IS_GCC && GCC_VERSION >= 110200
        depends on $(success,$(srctree)/arch/s390/tools/gcc-thunk-extern.sh $(CC))
@@ -590,18 +593,6 @@ config RELOCATABLE
          Note: this option exists only for documentation purposes, please do
          not remove it.
 
-config PIE_BUILD
-       def_bool CC_IS_CLANG && !$(cc-option,-munaligned-symbols)
-       help
-         If the compiler is unable to generate code that can manage unaligned
-         symbols, the kernel is linked as a position-independent executable
-         (PIE) and includes dynamic relocations that are processed early
-         during bootup.
-
-         For kpatch functionality, it is recommended to build the kernel
-         without the PIE_BUILD option. PIE_BUILD is only enabled when the
-         compiler lacks proper support for handling unaligned symbols.
-
 config RANDOMIZE_BASE
        bool "Randomize the address of the kernel image (KASLR)"
        default y
@@ -611,6 +602,25 @@ config RANDOMIZE_BASE
          as a security feature that deters exploit attempts relying on
          knowledge of the location of kernel internals.
 
+config KERNEL_IMAGE_BASE
+       hex "Kernel image base address"
+       range 0x100000 0x1FFFFFE0000000 if !KASAN
+       range 0x100000 0x1BFFFFE0000000 if KASAN
+       default 0x3FFE0000000 if !KASAN
+       default 0x7FFFE0000000 if KASAN
+       help
+         This is the address at which the kernel image is loaded in case
+         Kernel Address Space Layout Randomization (KASLR) is disabled.
+
+         In case the Protected virtualization guest support is enabled the
+         Ultravisor imposes a virtual address limit. If the value of this
+         option leads to the kernel image exceeding the Ultravisor limit,
+         this option is ignored and the image is loaded below the limit.
+
+         If the value of this option leads to the kernel image overlapping
+         the virtual memory where other data structures are located, this
+         option is ignored and the image is loaded above the structures.
+
 endmenu
 
 menu "Memory setup"
@@ -724,6 +734,33 @@ config EADM_SCH
          To compile this driver as a module, choose M here: the
          module will be called eadm_sch.
 
+config AP
+       def_tristate y
+       prompt "Support for Adjunct Processors (ap)"
+       help
+         This driver allows usage to Adjunct Processor (AP) devices via
+         the ap bus, cards and queues. Supported Adjunct Processors are
+         the CryptoExpress Cards (CEX).
+
+         To compile this driver as a module, choose M here: the
+         module will be called ap.
+
+         If unsure, say Y (default).
+
+config AP_DEBUG
+       def_bool n
+       prompt "Enable debug features for Adjunct Processor (ap) devices"
+       depends on AP
+       help
+         Say 'Y' here to enable some additional debug features for Adjunct
+         Processor (ap) devices.
+
+         There will be some more sysfs attributes displayed for ap queues.
+
+         Do not enable on production level kernel build.
+
+         If unsure, say N.
+
 config VFIO_CCW
        def_tristate n
        prompt "Support for VFIO-CCW subchannels"
@@ -740,7 +777,7 @@ config VFIO_AP
        prompt "VFIO support for AP devices"
        depends on KVM
        depends on VFIO
-       depends on ZCRYPT
+       depends on AP
        select VFIO_MDEV
        help
          This driver grants access to Adjunct Processor (AP) devices
index 2dbb2d2f22f99c265ba416176f49e3b9c12f5cf5..f2b21c7a70ef6ef3753bb5d343c9ac6f041eadc0 100644 (file)
@@ -14,14 +14,9 @@ KBUILD_AFLAGS_MODULE += -fPIC
 KBUILD_CFLAGS_MODULE += -fPIC
 KBUILD_AFLAGS  += -m64
 KBUILD_CFLAGS  += -m64
-ifdef CONFIG_PIE_BUILD
-KBUILD_CFLAGS  += -fPIE
-LDFLAGS_vmlinux        := -pie -z notext
-else
-KBUILD_CFLAGS  += $(call cc-option,-munaligned-symbols,)
-LDFLAGS_vmlinux        := --emit-relocs --discard-none
+KBUILD_CFLAGS  += -fPIC
+LDFLAGS_vmlinux        := -no-pie --emit-relocs --discard-none
 extra_tools    := relocs
-endif
 aflags_dwarf   := -Wa,-gdwarf-2
 KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
 ifndef CONFIG_AS_IS_LLVM
@@ -88,7 +83,6 @@ endif
 
 ifdef CONFIG_EXPOLINE
   ifdef CONFIG_EXPOLINE_EXTERN
-    KBUILD_LDFLAGS_MODULE += arch/s390/lib/expoline/expoline.o
     CC_FLAGS_EXPOLINE := -mindirect-branch=thunk-extern
     CC_FLAGS_EXPOLINE += -mfunction-return=thunk-extern
   else
@@ -167,11 +161,6 @@ vdso_prepare: prepare0
 vdso-install-y                 += arch/s390/kernel/vdso64/vdso64.so.dbg
 vdso-install-$(CONFIG_COMPAT)  += arch/s390/kernel/vdso32/vdso32.so.dbg
 
-ifdef CONFIG_EXPOLINE_EXTERN
-modules_prepare: expoline_prepare
-expoline_prepare: scripts
-       $(Q)$(MAKE) $(build)=arch/s390/lib/expoline arch/s390/lib/expoline/expoline.o
-endif
 endif
 
 # Don't use tabs in echo arguments
index 294f08a8811a2211442bbf659cbaddc93cd59dd6..070c9b2e905ffa36d1ba90ba840546191fb91422 100644 (file)
@@ -37,8 +37,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
 
 obj-y  := head.o als.o startup.o physmem_info.o ipl_parm.o ipl_report.o vmem.o
 obj-y  += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
-obj-y  += version.o pgm_check_info.o ctype.o ipl_data.o
-obj-y  += $(if $(CONFIG_PIE_BUILD),machine_kexec_reloc.o,relocs.o)
+obj-y  += version.o pgm_check_info.o ctype.o ipl_data.o relocs.o
 obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE))  += uv.o
 obj-$(CONFIG_RANDOMIZE_BASE)   += kaslr.o
 obj-y  += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
@@ -49,9 +48,7 @@ targets       := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y
 targets        += vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
 targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
 targets += vmlinux.bin.zst info.bin syms.bin vmlinux.syms $(obj-all)
-ifndef CONFIG_PIE_BUILD
 targets += relocs.S
-endif
 
 OBJECTS := $(addprefix $(obj)/,$(obj-y))
 OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
@@ -110,13 +107,11 @@ OBJCOPYFLAGS_vmlinux.bin := -O binary --remove-section=.comment --remove-section
 $(obj)/vmlinux.bin: vmlinux FORCE
        $(call if_changed,objcopy)
 
-ifndef CONFIG_PIE_BUILD
 CMD_RELOCS=arch/s390/tools/relocs
-quiet_cmd_relocs = RELOCS $@
+quiet_cmd_relocs = RELOCS  $@
        cmd_relocs = $(CMD_RELOCS) $< > $@
 $(obj)/relocs.S: vmlinux FORCE
        $(call if_changed,relocs)
-endif
 
 suffix-$(CONFIG_KERNEL_GZIP)  := .gz
 suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
index 567d60f78bbcca273378a6f66e748df167a4af13..18027fdc92b0c9b4b12170f28ac5ee4bd64ff03a 100644 (file)
@@ -17,7 +17,6 @@ struct machine_info {
 };
 
 struct vmlinux_info {
-       unsigned long default_lma;
        unsigned long entry;
        unsigned long image_size;       /* does not include .bss */
        unsigned long bss_size;         /* uncompressed image .bss size */
@@ -25,14 +24,8 @@ struct vmlinux_info {
        unsigned long bootdata_size;
        unsigned long bootdata_preserved_off;
        unsigned long bootdata_preserved_size;
-#ifdef CONFIG_PIE_BUILD
-       unsigned long dynsym_start;
-       unsigned long rela_dyn_start;
-       unsigned long rela_dyn_end;
-#else
        unsigned long got_start;
        unsigned long got_end;
-#endif
        unsigned long amode31_size;
        unsigned long init_mm_off;
        unsigned long swapper_pg_dir_off;
@@ -74,10 +67,11 @@ void sclp_early_setup_buffer(void);
 void print_pgm_check_info(void);
 unsigned long randomize_within_range(unsigned long size, unsigned long align,
                                     unsigned long min, unsigned long max);
-void setup_vmem(unsigned long asce_limit);
+void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit);
 void __printf(1, 2) decompressor_printk(const char *fmt, ...);
 void print_stacktrace(unsigned long sp);
 void error(char *m);
+int get_random(unsigned long limit, unsigned long *value);
 
 extern struct machine_info machine;
 
@@ -98,6 +92,10 @@ extern struct vmlinux_info _vmlinux_info;
 #define vmlinux _vmlinux_info
 
 #define __abs_lowcore_pa(x)    (((unsigned long)(x) - __abs_lowcore) % sizeof(struct lowcore))
+#define __kernel_va(x)         ((void *)((unsigned long)(x) - __kaslr_offset_phys + __kaslr_offset))
+#define __kernel_pa(x)         ((unsigned long)(x) - __kaslr_offset + __kaslr_offset_phys)
+#define __identity_va(x)       ((void *)((unsigned long)(x) + __identity_base))
+#define __identity_pa(x)       ((unsigned long)(x) - __identity_base)
 
 static inline bool intersects(unsigned long addr0, unsigned long size0,
                              unsigned long addr1, unsigned long size1)
index d762733a07530dbd14deebd01e18d78e0d1bba74..f478e8e9cbda4aa384b7ce2e42458036f900d906 100644 (file)
@@ -63,24 +63,13 @@ static unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE;
 #include "../../../../lib/decompress_unzstd.c"
 #endif
 
-#define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE)
-
 unsigned long mem_safe_offset(void)
 {
-       /*
-        * due to 4MB HEAD_SIZE for bzip2
-        * 'decompress_offset + vmlinux.image_size' could be larger than
-        * kernel at final position + its .bss, so take the larger of two
-        */
-       return max(decompress_offset + vmlinux.image_size,
-                  vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size);
+       return ALIGN(free_mem_end_ptr, PAGE_SIZE);
 }
 
-void *decompress_kernel(void)
+void deploy_kernel(void *output)
 {
-       void *output = (void *)decompress_offset;
-
        __decompress(_compressed_start, _compressed_end - _compressed_start,
                     NULL, NULL, output, vmlinux.image_size, NULL, error);
-       return output;
 }
index 92b81d2ea35d65f3d35fbf1ad053442cfaa8da6a..4f966f06bd65a36abbf25b6541031a64d6fa7f43 100644 (file)
@@ -2,11 +2,9 @@
 #ifndef BOOT_COMPRESSED_DECOMPRESSOR_H
 #define BOOT_COMPRESSED_DECOMPRESSOR_H
 
-#ifdef CONFIG_KERNEL_UNCOMPRESSED
-static inline void *decompress_kernel(void) { return NULL; }
-#else
-void *decompress_kernel(void);
-#endif
+#ifndef CONFIG_KERNEL_UNCOMPRESSED
 unsigned long mem_safe_offset(void);
+void deploy_kernel(void *output);
+#endif
 
 #endif /* BOOT_COMPRESSED_DECOMPRESSOR_H */
index 90602101e2aee871e71ab9f23a83e33830211290..bd3bf5ef472df2503c427e86b2f650c51f5469e3 100644 (file)
@@ -43,7 +43,7 @@ static int check_prng(void)
                return PRNG_MODE_TDES;
 }
 
-static int get_random(unsigned long limit, unsigned long *value)
+int get_random(unsigned long limit, unsigned long *value)
 {
        struct prng_parm prng = {
                /* initial parameter block for tdes mode, copied from libica */
index 97244cd7a206968398224c8e0ef6ed42402165cb..ea96275b0380393f1cd4088f6bdfdce0c505b493 100644 (file)
@@ -153,8 +153,10 @@ void print_pgm_check_info(void)
                decompressor_printk("Kernel command line: %s\n", early_command_line);
        decompressor_printk("Kernel fault: interruption code %04x ilc:%x\n",
                            S390_lowcore.pgm_code, S390_lowcore.pgm_ilc >> 1);
-       if (kaslr_enabled())
+       if (kaslr_enabled()) {
                decompressor_printk("Kernel random base: %lx\n", __kaslr_offset);
+               decompressor_printk("Kernel random base phys: %lx\n", __kaslr_offset_phys);
+       }
        decompressor_printk("PSW : %016lx %016lx (%pS)\n",
                            S390_lowcore.psw_save_area.mask,
                            S390_lowcore.psw_save_area.addr,
index 6cf89314209a628a530ec9142dc70e25aece3b9f..467283b112cdc778bc42e6bb52932cbc9a14c4b4 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/elf.h>
 #include <asm/page-states.h>
 #include <asm/boot_data.h>
+#include <asm/extmem.h>
 #include <asm/sections.h>
 #include <asm/maccess.h>
 #include <asm/cpu_mf.h>
@@ -18,7 +19,7 @@
 #include "boot.h"
 #include "uv.h"
 
-unsigned long __bootdata_preserved(__kaslr_offset);
+struct vm_layout __bootdata_preserved(vm_layout);
 unsigned long __bootdata_preserved(__abs_lowcore);
 unsigned long __bootdata_preserved(__memcpy_real_area);
 pte_t *__bootdata_preserved(memcpy_real_ptep);
@@ -29,7 +30,6 @@ unsigned long __bootdata_preserved(vmemmap_size);
 unsigned long __bootdata_preserved(MODULES_VADDR);
 unsigned long __bootdata_preserved(MODULES_END);
 unsigned long __bootdata_preserved(max_mappable);
-unsigned long __bootdata(ident_map_size);
 
 u64 __bootdata_preserved(stfle_fac_list[16]);
 u64 __bootdata_preserved(alt_stfle_fac_list[16]);
@@ -109,9 +109,19 @@ static void setup_lpp(void)
 }
 
 #ifdef CONFIG_KERNEL_UNCOMPRESSED
-unsigned long mem_safe_offset(void)
+static unsigned long mem_safe_offset(void)
 {
-       return vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size;
+       return (unsigned long)_compressed_start;
+}
+
+static void deploy_kernel(void *output)
+{
+       void *uncompressed_start = (void *)_compressed_start;
+
+       if (output == uncompressed_start)
+               return;
+       memmove(output, uncompressed_start, vmlinux.image_size);
+       memset(uncompressed_start, 0, vmlinux.image_size);
 }
 #endif
 
@@ -141,70 +151,18 @@ static void copy_bootdata(void)
        memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
 }
 
-#ifdef CONFIG_PIE_BUILD
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
-{
-       Elf64_Rela *rela_start, *rela_end, *rela;
-       int r_type, r_sym, rc;
-       Elf64_Addr loc, val;
-       Elf64_Sym *dynsym;
-
-       rela_start = (Elf64_Rela *) vmlinux.rela_dyn_start;
-       rela_end = (Elf64_Rela *) vmlinux.rela_dyn_end;
-       dynsym = (Elf64_Sym *) vmlinux.dynsym_start;
-       for (rela = rela_start; rela < rela_end; rela++) {
-               loc = rela->r_offset + offset;
-               val = rela->r_addend;
-               r_sym = ELF64_R_SYM(rela->r_info);
-               if (r_sym) {
-                       if (dynsym[r_sym].st_shndx != SHN_UNDEF)
-                               val += dynsym[r_sym].st_value + offset;
-               } else {
-                       /*
-                        * 0 == undefined symbol table index (STN_UNDEF),
-                        * used for R_390_RELATIVE, only add KASLR offset
-                        */
-                       val += offset;
-               }
-               r_type = ELF64_R_TYPE(rela->r_info);
-               rc = arch_kexec_do_relocs(r_type, (void *) loc, val, 0);
-               if (rc)
-                       error("Unknown relocation type");
-       }
-}
-
-static void kaslr_adjust_got(unsigned long offset) {}
-static void rescue_relocs(void) {}
-static void free_relocs(void) {}
-#else
-static int *vmlinux_relocs_64_start;
-static int *vmlinux_relocs_64_end;
-
-static void rescue_relocs(void)
-{
-       unsigned long size = __vmlinux_relocs_64_end - __vmlinux_relocs_64_start;
-
-       vmlinux_relocs_64_start = (void *)physmem_alloc_top_down(RR_RELOC, size, 0);
-       vmlinux_relocs_64_end = (void *)vmlinux_relocs_64_start + size;
-       memmove(vmlinux_relocs_64_start, __vmlinux_relocs_64_start, size);
-}
-
-static void free_relocs(void)
-{
-       physmem_free(RR_RELOC);
-}
-
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
+static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
+                               unsigned long offset, unsigned long phys_offset)
 {
        int *reloc;
        long loc;
 
        /* Adjust R_390_64 relocations */
-       for (reloc = vmlinux_relocs_64_start; reloc < vmlinux_relocs_64_end; reloc++) {
-               loc = (long)*reloc + offset;
+       for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) {
+               loc = (long)*reloc + phys_offset;
                if (loc < min_addr || loc > max_addr)
                        error("64-bit relocation outside of kernel!\n");
-               *(u64 *)loc += offset;
+               *(u64 *)loc += offset - __START_KERNEL;
        }
 }
 
@@ -217,9 +175,8 @@ static void kaslr_adjust_got(unsigned long offset)
         * reason. Adjust the GOT entries.
         */
        for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++)
-               *entry += offset;
+               *entry += offset - __START_KERNEL;
 }
-#endif
 
 /*
  * Merge information from several sources into a single ident_map_size value.
@@ -261,9 +218,26 @@ static void setup_ident_map_size(unsigned long max_physmem_end)
 #endif
 }
 
-static unsigned long setup_kernel_memory_layout(void)
+#define FIXMAP_SIZE    round_up(MEMCPY_REAL_SIZE + ABS_LOWCORE_MAP_SIZE, sizeof(struct lowcore))
+
+static unsigned long get_vmem_size(unsigned long identity_size,
+                                  unsigned long vmemmap_size,
+                                  unsigned long vmalloc_size,
+                                  unsigned long rte_size)
+{
+       unsigned long max_mappable, vsize;
+
+       max_mappable = max(identity_size, MAX_DCSS_ADDR);
+       vsize = round_up(SZ_2G + max_mappable, rte_size) +
+               round_up(vmemmap_size, rte_size) +
+               FIXMAP_SIZE + MODULES_LEN + KASLR_LEN;
+       return size_add(vsize, vmalloc_size);
+}
+
+static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
 {
        unsigned long vmemmap_start;
+       unsigned long kernel_start;
        unsigned long asce_limit;
        unsigned long rte_size;
        unsigned long pages;
@@ -275,12 +249,19 @@ static unsigned long setup_kernel_memory_layout(void)
        vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);
 
        /* choose kernel address space layout: 4 or 3 levels. */
-       vsize = round_up(ident_map_size, _REGION3_SIZE) + vmemmap_size +
-               MODULES_LEN + MEMCPY_REAL_SIZE + ABS_LOWCORE_MAP_SIZE;
-       vsize = size_add(vsize, vmalloc_size);
-       if (IS_ENABLED(CONFIG_KASAN) || (vsize > _REGION2_SIZE)) {
+       BUILD_BUG_ON(!IS_ALIGNED(__START_KERNEL, THREAD_SIZE));
+       BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE));
+       BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE);
+       vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE);
+       if (IS_ENABLED(CONFIG_KASAN) || __NO_KASLR_END_KERNEL > _REGION2_SIZE ||
+           (vsize > _REGION2_SIZE && kaslr_enabled())) {
                asce_limit = _REGION1_SIZE;
-               rte_size = _REGION2_SIZE;
+               if (__NO_KASLR_END_KERNEL > _REGION2_SIZE) {
+                       rte_size = _REGION2_SIZE;
+                       vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION2_SIZE);
+               } else {
+                       rte_size = _REGION3_SIZE;
+               }
        } else {
                asce_limit = _REGION2_SIZE;
                rte_size = _REGION3_SIZE;
@@ -290,38 +271,67 @@ static unsigned long setup_kernel_memory_layout(void)
         * Forcing modules and vmalloc area under the ultravisor
         * secure storage limit, so that any vmalloc allocation
         * we do could be used to back secure guest storage.
+        *
+        * Assume the secure storage limit always exceeds _REGION2_SIZE,
+        * otherwise asce_limit and rte_size would have been adjusted.
         */
        vmax = adjust_to_uv_max(asce_limit);
 #ifdef CONFIG_KASAN
+       BUILD_BUG_ON(__NO_KASLR_END_KERNEL > KASAN_SHADOW_START);
        /* force vmalloc and modules below kasan shadow */
        vmax = min(vmax, KASAN_SHADOW_START);
 #endif
-       __memcpy_real_area = round_down(vmax - MEMCPY_REAL_SIZE, PAGE_SIZE);
-       __abs_lowcore = round_down(__memcpy_real_area - ABS_LOWCORE_MAP_SIZE,
-                                  sizeof(struct lowcore));
-       MODULES_END = round_down(__abs_lowcore, _SEGMENT_SIZE);
+       vsize = min(vsize, vmax);
+       if (kaslr_enabled()) {
+               unsigned long kernel_end, kaslr_len, slots, pos;
+
+               kaslr_len = max(KASLR_LEN, vmax - vsize);
+               slots = DIV_ROUND_UP(kaslr_len - kernel_size, THREAD_SIZE);
+               if (get_random(slots, &pos))
+                       pos = 0;
+               kernel_end = vmax - pos * THREAD_SIZE;
+               kernel_start = round_down(kernel_end - kernel_size, THREAD_SIZE);
+       } else if (vmax < __NO_KASLR_END_KERNEL || vsize > __NO_KASLR_END_KERNEL) {
+               kernel_start = round_down(vmax - kernel_size, THREAD_SIZE);
+               decompressor_printk("The kernel base address is forced to %lx\n", kernel_start);
+       } else {
+               kernel_start = __NO_KASLR_START_KERNEL;
+       }
+       __kaslr_offset = kernel_start;
+
+       MODULES_END = round_down(kernel_start, _SEGMENT_SIZE);
        MODULES_VADDR = MODULES_END - MODULES_LEN;
        VMALLOC_END = MODULES_VADDR;
 
        /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
-       vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE);
+       vsize = (VMALLOC_END - FIXMAP_SIZE) / 2;
+       vsize = round_down(vsize, _SEGMENT_SIZE);
        vmalloc_size = min(vmalloc_size, vsize);
        VMALLOC_START = VMALLOC_END - vmalloc_size;
 
+       __memcpy_real_area = round_down(VMALLOC_START - MEMCPY_REAL_SIZE, PAGE_SIZE);
+       __abs_lowcore = round_down(__memcpy_real_area - ABS_LOWCORE_MAP_SIZE,
+                                  sizeof(struct lowcore));
+
        /* split remaining virtual space between 1:1 mapping & vmemmap array */
-       pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
+       pages = __abs_lowcore / (PAGE_SIZE + sizeof(struct page));
        pages = SECTION_ALIGN_UP(pages);
        /* keep vmemmap_start aligned to a top level region table entry */
-       vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size);
-       vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS);
-       /* maximum mappable address as seen by arch_get_mappable_range() */
-       max_mappable = vmemmap_start;
+       vmemmap_start = round_down(__abs_lowcore - pages * sizeof(struct page), rte_size);
        /* make sure identity map doesn't overlay with vmemmap */
        ident_map_size = min(ident_map_size, vmemmap_start);
        vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page);
-       /* make sure vmemmap doesn't overlay with vmalloc area */
-       VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START);
+       /* make sure vmemmap doesn't overlay with absolute lowcore area */
+       if (vmemmap_start + vmemmap_size > __abs_lowcore) {
+               vmemmap_size = SECTION_ALIGN_DOWN(ident_map_size / PAGE_SIZE) * sizeof(struct page);
+               ident_map_size = vmemmap_size / sizeof(struct page) * PAGE_SIZE;
+       }
        vmemmap = (struct page *)vmemmap_start;
+       /* maximum address for which linear mapping could be created (DCSS, memory) */
+       BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS));
+       max_mappable = max(ident_map_size, MAX_DCSS_ADDR);
+       max_mappable = min(max_mappable, vmemmap_start);
+       __identity_base = round_down(vmemmap_start - max_mappable, rte_size);
 
        return asce_limit;
 }
@@ -329,9 +339,9 @@ static unsigned long setup_kernel_memory_layout(void)
 /*
  * This function clears the BSS section of the decompressed Linux kernel and NOT the decompressor's.
  */
-static void clear_bss_section(unsigned long vmlinux_lma)
+static void clear_bss_section(unsigned long kernel_start)
 {
-       memset((void *)vmlinux_lma + vmlinux.image_size, 0, vmlinux.bss_size);
+       memset((void *)kernel_start + vmlinux.image_size, 0, vmlinux.bss_size);
 }
 
 /*
@@ -348,19 +358,12 @@ static void setup_vmalloc_size(void)
        vmalloc_size = max(size, vmalloc_size);
 }
 
-static void kaslr_adjust_vmlinux_info(unsigned long offset)
+static void kaslr_adjust_vmlinux_info(long offset)
 {
-       *(unsigned long *)(&vmlinux.entry) += offset;
        vmlinux.bootdata_off += offset;
        vmlinux.bootdata_preserved_off += offset;
-#ifdef CONFIG_PIE_BUILD
-       vmlinux.rela_dyn_start += offset;
-       vmlinux.rela_dyn_end += offset;
-       vmlinux.dynsym_start += offset;
-#else
        vmlinux.got_start += offset;
        vmlinux.got_end += offset;
-#endif
        vmlinux.init_mm_off += offset;
        vmlinux.swapper_pg_dir_off += offset;
        vmlinux.invalid_pg_dir_off += offset;
@@ -373,23 +376,30 @@ static void kaslr_adjust_vmlinux_info(unsigned long offset)
 #endif
 }
 
+static void fixup_vmlinux_info(void)
+{
+       vmlinux.entry -= __START_KERNEL;
+       kaslr_adjust_vmlinux_info(-__START_KERNEL);
+}
+
 void startup_kernel(void)
 {
-       unsigned long max_physmem_end;
-       unsigned long vmlinux_lma = 0;
+       unsigned long kernel_size = vmlinux.image_size + vmlinux.bss_size;
+       unsigned long nokaslr_offset_phys = mem_safe_offset();
        unsigned long amode31_lma = 0;
+       unsigned long max_physmem_end;
        unsigned long asce_limit;
        unsigned long safe_addr;
-       void *img;
        psw_t psw;
 
+       fixup_vmlinux_info();
        setup_lpp();
-       safe_addr = mem_safe_offset();
+       safe_addr = PAGE_ALIGN(nokaslr_offset_phys + kernel_size);
 
        /*
-        * Reserve decompressor memory together with decompression heap, buffer and
-        * memory which might be occupied by uncompressed kernel at default 1Mb
-        * position (if KASLR is off or failed).
+        * Reserve decompressor memory together with decompression heap,
+        * buffer and memory which might be occupied by uncompressed kernel
+        * (if KASLR is off or failed).
         */
        physmem_reserve(RR_DECOMPRESSOR, 0, safe_addr);
        if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && parmarea.initrd_size)
@@ -409,40 +419,39 @@ void startup_kernel(void)
        max_physmem_end = detect_max_physmem_end();
        setup_ident_map_size(max_physmem_end);
        setup_vmalloc_size();
-       asce_limit = setup_kernel_memory_layout();
+       asce_limit = setup_kernel_memory_layout(kernel_size);
        /* got final ident_map_size, physmem allocations could be performed now */
        physmem_set_usable_limit(ident_map_size);
        detect_physmem_online_ranges(max_physmem_end);
        save_ipl_cert_comp_list();
        rescue_initrd(safe_addr, ident_map_size);
-       rescue_relocs();
 
-       if (kaslr_enabled()) {
-               vmlinux_lma = randomize_within_range(vmlinux.image_size + vmlinux.bss_size,
-                                                    THREAD_SIZE, vmlinux.default_lma,
-                                                    ident_map_size);
-               if (vmlinux_lma) {
-                       __kaslr_offset = vmlinux_lma - vmlinux.default_lma;
-                       kaslr_adjust_vmlinux_info(__kaslr_offset);
-               }
-       }
-       vmlinux_lma = vmlinux_lma ?: vmlinux.default_lma;
-       physmem_reserve(RR_VMLINUX, vmlinux_lma, vmlinux.image_size + vmlinux.bss_size);
-
-       if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
-               img = decompress_kernel();
-               memmove((void *)vmlinux_lma, img, vmlinux.image_size);
-       } else if (__kaslr_offset) {
-               img = (void *)vmlinux.default_lma;
-               memmove((void *)vmlinux_lma, img, vmlinux.image_size);
-               memset(img, 0, vmlinux.image_size);
-       }
+       if (kaslr_enabled())
+               __kaslr_offset_phys = randomize_within_range(kernel_size, THREAD_SIZE, 0, ident_map_size);
+       if (!__kaslr_offset_phys)
+               __kaslr_offset_phys = nokaslr_offset_phys;
+       kaslr_adjust_vmlinux_info(__kaslr_offset_phys);
+       physmem_reserve(RR_VMLINUX, __kaslr_offset_phys, kernel_size);
+       deploy_kernel((void *)__kaslr_offset_phys);
 
        /* vmlinux decompression is done, shrink reserved low memory */
        physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);
+
+       /*
+        * In case KASLR is enabled the randomized location of .amode31
+        * section might overlap with .vmlinux.relocs section. To avoid that
+        * the below randomize_within_range() could have been called with
+        * __vmlinux_relocs_64_end as the lower range address. However,
+        * .amode31 section is written to by the decompressed kernel - at
+        * that time the contents of .vmlinux.relocs is not needed anymore.
+        * Conversly, .vmlinux.relocs is read only by the decompressor, even
+        * before the kernel started. Therefore, in case the two sections
+        * overlap there is no risk of corrupting any data.
+        */
        if (kaslr_enabled())
                amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G);
-       amode31_lma = amode31_lma ?: vmlinux.default_lma - vmlinux.amode31_size;
+       if (!amode31_lma)
+               amode31_lma = __kaslr_offset_phys - vmlinux.amode31_size;
        physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);
 
        /*
@@ -458,23 +467,23 @@ void startup_kernel(void)
         * - copy_bootdata() must follow setup_vmem() to propagate changes
         *   to bootdata made by setup_vmem()
         */
-       clear_bss_section(vmlinux_lma);
-       kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size, __kaslr_offset);
+       clear_bss_section(__kaslr_offset_phys);
+       kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size,
+                           __kaslr_offset, __kaslr_offset_phys);
        kaslr_adjust_got(__kaslr_offset);
-       free_relocs();
-       setup_vmem(asce_limit);
+       setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
        copy_bootdata();
 
        /*
         * Save KASLR offset for early dumps, before vmcore_info is set.
         * Mark as uneven to distinguish from real vmcore_info pointer.
         */
-       S390_lowcore.vmcore_info = __kaslr_offset ? __kaslr_offset | 0x1UL : 0;
+       S390_lowcore.vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0;
 
        /*
         * Jump to the decompressed kernel entry point and switch DAT mode on.
         */
-       psw.addr = vmlinux.entry;
+       psw.addr = __kaslr_offset + vmlinux.entry;
        psw.mask = PSW_KERNEL_BITS;
        __load_psw(psw);
 }
index 09b10bb6e4d0700fac2b00526a575c723f092ca7..96d48b7112d40b09a6195f7b27fccd967ccbeab2 100644 (file)
@@ -27,6 +27,8 @@ enum populate_mode {
        POPULATE_NONE,
        POPULATE_DIRECT,
        POPULATE_ABS_LOWCORE,
+       POPULATE_IDENTITY,
+       POPULATE_KERNEL,
 #ifdef CONFIG_KASAN
        POPULATE_KASAN_MAP_SHADOW,
        POPULATE_KASAN_ZERO_SHADOW,
@@ -54,7 +56,7 @@ static inline void kasan_populate(unsigned long start, unsigned long end, enum p
        pgtable_populate(start, end, mode);
 }
 
-static void kasan_populate_shadow(void)
+static void kasan_populate_shadow(unsigned long kernel_start, unsigned long kernel_end)
 {
        pmd_t pmd_z = __pmd(__pa(kasan_early_shadow_pte) | _SEGMENT_ENTRY);
        pud_t pud_z = __pud(__pa(kasan_early_shadow_pmd) | _REGION3_ENTRY);
@@ -76,44 +78,20 @@ static void kasan_populate_shadow(void)
        __arch_set_page_dat(kasan_early_shadow_pmd, 1UL << CRST_ALLOC_ORDER);
        __arch_set_page_dat(kasan_early_shadow_pte, 1);
 
-       /*
-        * Current memory layout:
-        * +- 0 -------------+         +- shadow start -+
-        * |1:1 ident mapping|        /|1/8 of ident map|
-        * |                 |       / |                |
-        * +-end of ident map+      /  +----------------+
-        * | ... gap ...     |     /   |    kasan       |
-        * |                 |    /    |  zero page     |
-        * +- vmalloc area  -+   /     |   mapping      |
-        * | vmalloc_size    |  /      | (untracked)    |
-        * +- modules vaddr -+ /       +----------------+
-        * | 2Gb             |/        |    unmapped    | allocated per module
-        * +- shadow start  -+         +----------------+
-        * | 1/8 addr space  |         | zero pg mapping| (untracked)
-        * +- shadow end ----+---------+- shadow end ---+
-        *
-        * Current memory layout (KASAN_VMALLOC):
-        * +- 0 -------------+         +- shadow start -+
-        * |1:1 ident mapping|        /|1/8 of ident map|
-        * |                 |       / |                |
-        * +-end of ident map+      /  +----------------+
-        * | ... gap ...     |     /   | kasan zero page| (untracked)
-        * |                 |    /    | mapping        |
-        * +- vmalloc area  -+   /     +----------------+
-        * | vmalloc_size    |  /      |shallow populate|
-        * +- modules vaddr -+ /       +----------------+
-        * | 2Gb             |/        |shallow populate|
-        * +- shadow start  -+         +----------------+
-        * | 1/8 addr space  |         | zero pg mapping| (untracked)
-        * +- shadow end ----+---------+- shadow end ---+
-        */
-
        for_each_physmem_usable_range(i, &start, &end) {
-               kasan_populate(start, end, POPULATE_KASAN_MAP_SHADOW);
-               if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260)
-                       kasan_populate(memgap_start, start, POPULATE_KASAN_ZERO_SHADOW);
+               kasan_populate((unsigned long)__identity_va(start),
+                              (unsigned long)__identity_va(end),
+                              POPULATE_KASAN_MAP_SHADOW);
+               if (memgap_start && physmem_info.info_source == MEM_DETECT_DIAG260) {
+                       kasan_populate((unsigned long)__identity_va(memgap_start),
+                                      (unsigned long)__identity_va(start),
+                                      POPULATE_KASAN_ZERO_SHADOW);
+               }
                memgap_start = end;
        }
+       kasan_populate(kernel_start, kernel_end, POPULATE_KASAN_MAP_SHADOW);
+       kasan_populate(0, (unsigned long)__identity_va(0), POPULATE_KASAN_ZERO_SHADOW);
+       kasan_populate(AMODE31_START, AMODE31_END, POPULATE_KASAN_ZERO_SHADOW);
        if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
                untracked_end = VMALLOC_START;
                /* shallowly populate kasan shadow for vmalloc and modules */
@@ -122,8 +100,9 @@ static void kasan_populate_shadow(void)
                untracked_end = MODULES_VADDR;
        }
        /* populate kasan shadow for untracked memory */
-       kasan_populate(ident_map_size, untracked_end, POPULATE_KASAN_ZERO_SHADOW);
-       kasan_populate(MODULES_END, _REGION1_SIZE, POPULATE_KASAN_ZERO_SHADOW);
+       kasan_populate((unsigned long)__identity_va(ident_map_size), untracked_end,
+                      POPULATE_KASAN_ZERO_SHADOW);
+       kasan_populate(kernel_end, _REGION1_SIZE, POPULATE_KASAN_ZERO_SHADOW);
 }
 
 static bool kasan_pgd_populate_zero_shadow(pgd_t *pgd, unsigned long addr,
@@ -180,7 +159,9 @@ static bool kasan_pte_populate_zero_shadow(pte_t *pte, enum populate_mode mode)
 }
 #else
 
-static inline void kasan_populate_shadow(void) {}
+static inline void kasan_populate_shadow(unsigned long kernel_start, unsigned long kernel_end)
+{
+}
 
 static inline bool kasan_pgd_populate_zero_shadow(pgd_t *pgd, unsigned long addr,
                                                  unsigned long end, enum populate_mode mode)
@@ -263,6 +244,10 @@ static unsigned long _pa(unsigned long addr, unsigned long size, enum populate_m
                return addr;
        case POPULATE_ABS_LOWCORE:
                return __abs_lowcore_pa(addr);
+       case POPULATE_KERNEL:
+               return __kernel_pa(addr);
+       case POPULATE_IDENTITY:
+               return __identity_pa(addr);
 #ifdef CONFIG_KASAN
        case POPULATE_KASAN_MAP_SHADOW:
                addr = physmem_alloc_top_down(RR_VMEM, size, size);
@@ -274,15 +259,22 @@ static unsigned long _pa(unsigned long addr, unsigned long size, enum populate_m
        }
 }
 
-static bool can_large_pud(pud_t *pu_dir, unsigned long addr, unsigned long end)
+static bool large_allowed(enum populate_mode mode)
+{
+       return (mode == POPULATE_DIRECT) || (mode == POPULATE_IDENTITY);
+}
+
+static bool can_large_pud(pud_t *pu_dir, unsigned long addr, unsigned long end,
+                         enum populate_mode mode)
 {
-       return machine.has_edat2 &&
+       return machine.has_edat2 && large_allowed(mode) &&
               IS_ALIGNED(addr, PUD_SIZE) && (end - addr) >= PUD_SIZE;
 }
 
-static bool can_large_pmd(pmd_t *pm_dir, unsigned long addr, unsigned long end)
+static bool can_large_pmd(pmd_t *pm_dir, unsigned long addr, unsigned long end,
+                         enum populate_mode mode)
 {
-       return machine.has_edat1 &&
+       return machine.has_edat1 && large_allowed(mode) &&
               IS_ALIGNED(addr, PMD_SIZE) && (end - addr) >= PMD_SIZE;
 }
 
@@ -322,7 +314,7 @@ static void pgtable_pmd_populate(pud_t *pud, unsigned long addr, unsigned long e
                if (pmd_none(*pmd)) {
                        if (kasan_pmd_populate_zero_shadow(pmd, addr, next, mode))
                                continue;
-                       if (can_large_pmd(pmd, addr, next)) {
+                       if (can_large_pmd(pmd, addr, next, mode)) {
                                entry = __pmd(_pa(addr, _SEGMENT_SIZE, mode));
                                entry = set_pmd_bit(entry, SEGMENT_KERNEL);
                                if (!machine.has_nx)
@@ -355,7 +347,7 @@ static void pgtable_pud_populate(p4d_t *p4d, unsigned long addr, unsigned long e
                if (pud_none(*pud)) {
                        if (kasan_pud_populate_zero_shadow(pud, addr, next, mode))
                                continue;
-                       if (can_large_pud(pud, addr, next)) {
+                       if (can_large_pud(pud, addr, next, mode)) {
                                entry = __pud(_pa(addr, _REGION3_SIZE, mode));
                                entry = set_pud_bit(entry, REGION3_KERNEL);
                                if (!machine.has_nx)
@@ -418,11 +410,12 @@ static void pgtable_populate(unsigned long addr, unsigned long end, enum populat
        }
 }
 
-void setup_vmem(unsigned long asce_limit)
+void setup_vmem(unsigned long kernel_start, unsigned long kernel_end, unsigned long asce_limit)
 {
        unsigned long start, end;
        unsigned long asce_type;
        unsigned long asce_bits;
+       pgd_t *init_mm_pgd;
        int i;
 
        /*
@@ -433,6 +426,15 @@ void setup_vmem(unsigned long asce_limit)
        for_each_physmem_online_range(i, &start, &end)
                __arch_set_page_nodat((void *)start, (end - start) >> PAGE_SHIFT);
 
+       /*
+        * init_mm->pgd contains virtual address of swapper_pg_dir.
+        * It is unusable at this stage since DAT is yet off. Swap
+        * it for physical address of swapper_pg_dir and restore
+        * the virtual address after all page tables are created.
+        */
+       init_mm_pgd = init_mm.pgd;
+       init_mm.pgd = (pgd_t *)swapper_pg_dir;
+
        if (asce_limit == _REGION1_SIZE) {
                asce_type = _REGION2_ENTRY_EMPTY;
                asce_bits = _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH;
@@ -453,15 +455,20 @@ void setup_vmem(unsigned long asce_limit)
         * the lowcore and create the identity mapping only afterwards.
         */
        pgtable_populate(0, sizeof(struct lowcore), POPULATE_DIRECT);
-       for_each_physmem_usable_range(i, &start, &end)
-               pgtable_populate(start, end, POPULATE_DIRECT);
+       for_each_physmem_usable_range(i, &start, &end) {
+               pgtable_populate((unsigned long)__identity_va(start),
+                                (unsigned long)__identity_va(end),
+                                POPULATE_IDENTITY);
+       }
+       pgtable_populate(kernel_start, kernel_end, POPULATE_KERNEL);
+       pgtable_populate(AMODE31_START, AMODE31_END, POPULATE_DIRECT);
        pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
                         POPULATE_ABS_LOWCORE);
        pgtable_populate(__memcpy_real_area, __memcpy_real_area + PAGE_SIZE,
                         POPULATE_NONE);
-       memcpy_real_ptep = __virt_to_kpte(__memcpy_real_area);
+       memcpy_real_ptep = __identity_va(__virt_to_kpte(__memcpy_real_area));
 
-       kasan_populate_shadow();
+       kasan_populate_shadow(kernel_start, kernel_end);
 
        S390_lowcore.kernel_asce.val = swapper_pg_dir | asce_bits;
        S390_lowcore.user_asce = s390_invalid_asce;
@@ -471,4 +478,5 @@ void setup_vmem(unsigned long asce_limit)
        local_ctl_load(13, &S390_lowcore.kernel_asce);
 
        init_mm.context.asce = S390_lowcore.kernel_asce.val;
+       init_mm.pgd = init_mm_pgd;
 }
index 3d7ea585ab9935b9792412d319fc28bfc03de92f..1fe5a1d3ff60d6f39887bd545677eea28afbe5d1 100644 (file)
@@ -99,8 +99,16 @@ SECTIONS
 
        _decompressor_end = .;
 
+       . = ALIGN(4);
+       .vmlinux.relocs : {
+               __vmlinux_relocs_64_start = .;
+               *(.vmlinux.relocs_64)
+               __vmlinux_relocs_64_end = .;
+       }
+
 #ifdef CONFIG_KERNEL_UNCOMPRESSED
-       . = 0x100000;
+       . = ALIGN(PAGE_SIZE);
+       . += AMODE31_SIZE;              /* .amode31 section */
 #else
        . = ALIGN(8);
 #endif
@@ -110,24 +118,6 @@ SECTIONS
                _compressed_end = .;
        }
 
-#ifndef CONFIG_PIE_BUILD
-       /*
-        * When the kernel is built with CONFIG_KERNEL_UNCOMPRESSED, the entire
-        * uncompressed vmlinux.bin is positioned in the bzImage decompressor
-        * image at the default kernel LMA of 0x100000, enabling it to be
-        * executed in-place. However, the size of .vmlinux.relocs could be
-        * large enough to cause an overlap with the uncompressed kernel at the
-        * address 0x100000. To address this issue, .vmlinux.relocs is
-        * positioned after the .rodata.compressed.
-        */
-       . = ALIGN(4);
-       .vmlinux.relocs : {
-               __vmlinux_relocs_64_start = .;
-               *(.vmlinux.relocs_64)
-               __vmlinux_relocs_64_end = .;
-       }
-#endif
-
 #define SB_TRAILER_SIZE 32
        /* Trailer needed for Secure Boot */
        . += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
index 99f7e1f2b70aff61da33cc06bc0e7455394150a8..99ea3f12c5d2ab2990c06b73602a3c513f361f7f 100644 (file)
@@ -125,8 +125,19 @@ struct s390_pxts_ctx {
 static inline int __paes_keyblob2pkey(struct key_blob *kb,
                                     struct pkey_protkey *pk)
 {
-       return pkey_keyblob2pkey(kb->key, kb->keylen,
-                                pk->protkey, &pk->len, &pk->type);
+       int i, ret = -EIO;
+
+       /* try three times in case of busy card */
+       for (i = 0; ret && i < 3; i++) {
+               if (ret == -EBUSY && in_task()) {
+                       if (msleep_interruptible(1000))
+                               return -EINTR;
+               }
+               ret = pkey_keyblob2pkey(kb->key, kb->keylen,
+                                       pk->protkey, &pk->len, &pk->type);
+       }
+
+       return ret;
 }
 
 static inline int __paes_convert_key(struct s390_paes_ctx *ctx)
index 43ac4a64f49b0227348d454d6ec30c083635a978..395b02d6a1337494da76135608d91a22f20a9bc3 100644 (file)
@@ -223,13 +223,18 @@ static inline struct ap_queue_status ap_zapq(ap_qid_t qid, int fbit)
  * config info as returned by the ap_qci() function.
  */
 struct ap_config_info {
-       unsigned int apsc        : 1;   /* S bit */
-       unsigned int apxa        : 1;   /* N bit */
-       unsigned int qact        : 1;   /* C bit */
-       unsigned int rc8a        : 1;   /* R bit */
-       unsigned int             : 4;
-       unsigned int apsb        : 1;   /* B bit */
-       unsigned int             : 23;
+       union {
+               unsigned int flags;
+               struct {
+                       unsigned int apsc        : 1;   /* S bit */
+                       unsigned int apxa        : 1;   /* N bit */
+                       unsigned int qact        : 1;   /* C bit */
+                       unsigned int rc8a        : 1;   /* R bit */
+                       unsigned int             : 4;
+                       unsigned int apsb        : 1;   /* B bit */
+                       unsigned int             : 23;
+               };
+       };
        unsigned char na;               /* max # of APs - 1 */
        unsigned char nd;               /* max # of Domains - 1 */
        unsigned char _reserved0[10];
@@ -544,15 +549,4 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
        return reg1.status;
 }
 
-/*
- * Interface to tell the AP bus code that a configuration
- * change has happened. The bus code should at least do
- * an ap bus resource rescan.
- */
-#if IS_ENABLED(CONFIG_ZCRYPT)
-void ap_bus_cfg_chg(void);
-#else
-static inline void ap_bus_cfg_chg(void){}
-#endif
-
 #endif /* _ASM_S390_AP_H_ */
index 56096ae26f296b22a350592d6c354ea83e03a359..f662eb4b9246fb5fc556403e655643ef6ba071d4 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/kvm_host.h>
 #include <linux/ftrace.h>
 #include <asm/fpu.h>
+#include <asm/nospec-branch.h>
 #include <asm-generic/asm-prototypes.h>
 
 __int128_t __ashlti3(__int128_t a, int b);
index bb48ea380c0d1de30e534327abafa377c45fb8e5..bb78159d8042a9145f4a265840fb5183ec8906d9 100644 (file)
@@ -11,6 +11,9 @@
 
 #include <uapi/asm/chsc.h>
 
+/* struct from linux/notifier.h */
+struct notifier_block;
+
 /**
  * Operation codes for CHSC PNSO:
  *    PNSO_OC_NET_BRIDGE_INFO - only addresses that are visible to a bridgeport
@@ -66,4 +69,16 @@ struct chsc_pnso_area {
        struct chsc_pnso_naid_l2 entries[];
 } __packed __aligned(PAGE_SIZE);
 
+/*
+ * notifier interface - registered notifiers gets called on
+ * the following events:
+ * - ap config changed (CHSC_NOTIFY_AP_CFG)
+ */
+enum chsc_notify_type {
+       CHSC_NOTIFY_AP_CFG = 3,
+};
+
+int chsc_notifier_register(struct notifier_block *nb);
+int chsc_notifier_unregister(struct notifier_block *nb);
+
 #endif /* _ASM_S390_CHSC_H */
index 4f21ae561e4ddc7af7bc7a21f848f0fe4315ab59..390906b8e386e609f760d891484133b1c0fbea79 100644 (file)
@@ -9,6 +9,7 @@
 #define CFI_DEF_CFA_OFFSET     .cfi_def_cfa_offset
 #define CFI_ADJUST_CFA_OFFSET  .cfi_adjust_cfa_offset
 #define CFI_RESTORE            .cfi_restore
+#define CFI_REL_OFFSET         .cfi_rel_offset
 
 #ifdef CONFIG_AS_CFI_VAL_OFFSET
 #define CFI_VAL_OFFSET         .cfi_val_offset
index 568fd81bb77b516de65c83933f6518f43c26d41f..e0a06060afddc8206835be2971e8b82e920cf4c9 100644 (file)
@@ -8,6 +8,13 @@
 #define _ASM_S390X_DCSS_H
 #ifndef __ASSEMBLY__
 
+/*
+ * DCSS segment is defined as a contiguous range of pages using DEFSEG command.
+ * The range start and end is a page number with a value less than or equal to
+ * 0x7ffffff (see CP Commands and Utilities Reference).
+ */
+#define MAX_DCSS_ADDR  (512UL * SZ_1G)
+
 /* possible values for segment type as returned by segment_info */
 #define SEG_TYPE_SW 0
 #define SEG_TYPE_EW 1
index 621f23d5ae30a6a05e39e3bf54df1a3b80011f68..77e479d44f1e375d3244ea6e526de2670d36d9d2 100644 (file)
@@ -8,12 +8,8 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_CC_IS_CLANG
-/* https://llvm.org/pr41424 */
-#define ftrace_return_address(n) 0UL
-#else
-#define ftrace_return_address(n) __builtin_return_address(n)
-#endif
+unsigned long return_address(unsigned int n);
+#define ftrace_return_address(n) return_address(n)
 
 void ftrace_caller(void);
 
index 5cc46e0dde620decefade93948238eb493036e98..9725586f42597cfa9b9660bd85e8f0bef91e455b 100644 (file)
@@ -146,7 +146,7 @@ int gmap_mprotect_notify(struct gmap *, unsigned long start,
 
 void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
                             unsigned long gaddr, unsigned long vmaddr);
-int gmap_mark_unmergeable(void);
+int s390_disable_cow_sharing(void);
 void s390_unlist_old_asce(struct gmap *gmap);
 int s390_replace_asce(struct gmap *gmap);
 void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns);
index bb1b4bef1878b2bf9359ea41943113c729c5d594..4c2dc7abc2858604954b5c33f472c87178ae2daf 100644 (file)
@@ -32,6 +32,11 @@ typedef struct {
        unsigned int uses_skeys:1;
        /* The mmu context uses CMM. */
        unsigned int uses_cmm:1;
+       /*
+        * The mmu context allows COW-sharing of memory pages (KSM, zeropage).
+        * Note that COW-sharing during fork() is currently always allowed.
+        */
+       unsigned int allow_cow_sharing:1;
        /* The gmaps associated with this context are allowed to use huge pages. */
        unsigned int allow_gmap_hpage_1m:1;
 } mm_context_t;
index 929af18b09081a0893559aec76f2ac869bf79fff..a7789a9f6218683c5e61f2540ef44c49ad288d98 100644 (file)
@@ -35,6 +35,7 @@ static inline int init_new_context(struct task_struct *tsk,
        mm->context.has_pgste = 0;
        mm->context.uses_skeys = 0;
        mm->context.uses_cmm = 0;
+       mm->context.allow_cow_sharing = 1;
        mm->context.allow_gmap_hpage_1m = 0;
 #endif
        switch (mm->context.asce_limit) {
index 82725cf783c70cfcaf511931be6b26dfc4522303..b9c1f3cae84267d05c93f473414c31ce82157eb8 100644 (file)
@@ -17,6 +17,26 @@ static inline bool nospec_uses_trampoline(void)
        return __is_defined(CC_USING_EXPOLINE) && !nospec_disable;
 }
 
+#ifdef CONFIG_EXPOLINE_EXTERN
+
+void __s390_indirect_jump_r1(void);
+void __s390_indirect_jump_r2(void);
+void __s390_indirect_jump_r3(void);
+void __s390_indirect_jump_r4(void);
+void __s390_indirect_jump_r5(void);
+void __s390_indirect_jump_r6(void);
+void __s390_indirect_jump_r7(void);
+void __s390_indirect_jump_r8(void);
+void __s390_indirect_jump_r9(void);
+void __s390_indirect_jump_r10(void);
+void __s390_indirect_jump_r11(void);
+void __s390_indirect_jump_r12(void);
+void __s390_indirect_jump_r13(void);
+void __s390_indirect_jump_r14(void);
+void __s390_indirect_jump_r15(void);
+
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_S390_EXPOLINE_H */
index 7a946c42ad13b8de2807d755a63a78ca292f10e6..cb15dd25bf219692f9e3a168d3786ac3d321ff49 100644 (file)
  */
        .macro __THUNK_PROLOG_NAME name
 #ifdef CONFIG_EXPOLINE_EXTERN
-       .pushsection .text,"ax",@progbits
-       __ALIGN
+       SYM_CODE_START(\name)
 #else
        .pushsection .text.\name,"axG",@progbits,\name,comdat
-#endif
        .globl \name
        .hidden \name
        .type \name,@function
 \name:
        CFI_STARTPROC
+#endif
        .endm
 
        .macro __THUNK_EPILOG_NAME name
-       CFI_ENDPROC
 #ifdef CONFIG_EXPOLINE_EXTERN
-       .size \name, .-\name
-#endif
+       SYM_CODE_END(\name)
+       EXPORT_SYMBOL(\name)
+#else
+       CFI_ENDPROC
        .popsection
+#endif
        .endm
 
        .macro __THUNK_PROLOG_BR r1
index a4d2e103f1161b93d4d183918de5d19697d60f94..3ee9e8f5ceae7a1353673125048d08332aef7d34 100644 (file)
 #define OS_INFO_VMCOREINFO     0
 #define OS_INFO_REIPL_BLOCK    1
 #define OS_INFO_FLAGS_ENTRY    2
+#define OS_INFO_RESERVED       3
+#define OS_INFO_IDENTITY_BASE  4
+#define OS_INFO_KASLR_OFFSET   5
+#define OS_INFO_KASLR_OFF_PHYS 6
+#define OS_INFO_VMEMMAP                7
+#define OS_INFO_AMODE31_START  8
+#define OS_INFO_AMODE31_END    9
+#define OS_INFO_IMAGE_START    10
+#define OS_INFO_IMAGE_END      11
+#define OS_INFO_IMAGE_PHYS     12
+#define OS_INFO_MAX            13
 
 #define OS_INFO_FLAG_REIPL_CLEAR       (1UL << 0)
 
 struct os_info_entry {
-       u64     addr;
+       union {
+               u64     addr;
+               u64     val;
+       };
        u64     size;
        u32     csum;
 } __packed;
@@ -33,17 +47,24 @@ struct os_info {
        u16     version_minor;
        u64     crashkernel_addr;
        u64     crashkernel_size;
-       struct os_info_entry entry[3];
-       u8      reserved[4004];
+       struct os_info_entry entry[OS_INFO_MAX];
+       u8      reserved[3804];
 } __packed;
 
 void os_info_init(void);
-void os_info_entry_add(int nr, void *ptr, u64 len);
+void os_info_entry_add_data(int nr, void *ptr, u64 len);
+void os_info_entry_add_val(int nr, u64 val);
 void os_info_crashkernel_add(unsigned long base, unsigned long size);
 u32 os_info_csum(struct os_info *os_info);
 
 #ifdef CONFIG_CRASH_DUMP
 void *os_info_old_entry(int nr, unsigned long *size);
+static inline unsigned long os_info_old_value(int nr)
+{
+       unsigned long size;
+
+       return (unsigned long)os_info_old_entry(nr, &size);
+}
 #else
 static inline void *os_info_old_entry(int nr, unsigned long *size)
 {
index 9381879f7ecf6c4c59097884b9135cb1b9a84559..224ff9d433eadd58c4d4b904686096ffeb80602a 100644 (file)
@@ -178,19 +178,52 @@ int arch_make_page_accessible(struct page *page);
 #define HAVE_ARCH_MAKE_PAGE_ACCESSIBLE
 #endif
 
-#define __PAGE_OFFSET          0x0UL
-#define PAGE_OFFSET            0x0UL
+struct vm_layout {
+       unsigned long kaslr_offset;
+       unsigned long kaslr_offset_phys;
+       unsigned long identity_base;
+       unsigned long identity_size;
+};
 
-#define __pa_nodebug(x)                ((unsigned long)(x))
+extern struct vm_layout vm_layout;
+
+#define __kaslr_offset         vm_layout.kaslr_offset
+#define __kaslr_offset_phys    vm_layout.kaslr_offset_phys
+#define __identity_base                vm_layout.identity_base
+#define ident_map_size         vm_layout.identity_size
+
+static inline unsigned long kaslr_offset(void)
+{
+       return __kaslr_offset;
+}
+
+extern int __kaslr_enabled;
+static inline int kaslr_enabled(void)
+{
+       if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
+               return __kaslr_enabled;
+       return 0;
+}
+
+#define __PAGE_OFFSET          __identity_base
+#define PAGE_OFFSET            __PAGE_OFFSET
 
 #ifdef __DECOMPRESSOR
 
+#define __pa_nodebug(x)                ((unsigned long)(x))
 #define __pa(x)                        __pa_nodebug(x)
 #define __pa32(x)              __pa(x)
 #define __va(x)                        ((void *)(unsigned long)(x))
 
 #else /* __DECOMPRESSOR */
 
+static inline unsigned long __pa_nodebug(unsigned long x)
+{
+       if (x < __kaslr_offset)
+               return x - __identity_base;
+       return x - __kaslr_offset + __kaslr_offset_phys;
+}
+
 #ifdef CONFIG_DEBUG_VIRTUAL
 
 unsigned long __phys_addr(unsigned long x, bool is_31bit);
@@ -206,7 +239,7 @@ static inline unsigned long __phys_addr(unsigned long x, bool is_31bit)
 
 #define __pa(x)                        __phys_addr((unsigned long)(x), false)
 #define __pa32(x)              __phys_addr((unsigned long)(x), true)
-#define __va(x)                        ((void *)(unsigned long)(x))
+#define __va(x)                        ((void *)((unsigned long)(x) + __identity_base))
 
 #endif /* __DECOMPRESSOR */
 
@@ -231,7 +264,7 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
 #define virt_to_page(kaddr)    pfn_to_page(virt_to_pfn(kaddr))
 #define page_to_virt(page)     pfn_to_virt(page_to_pfn(page))
 
-#define virt_addr_valid(kaddr) pfn_valid(phys_to_pfn(__pa_nodebug(kaddr)))
+#define virt_addr_valid(kaddr) pfn_valid(phys_to_pfn(__pa_nodebug((unsigned long)(kaddr))))
 
 #define VM_DATA_DEFAULT_FLAGS  VM_DATA_FLAGS_NON_EXEC
 
@@ -240,4 +273,11 @@ static inline unsigned long virt_to_pfn(const void *kaddr)
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
 
+#define AMODE31_SIZE           (3 * PAGE_SIZE)
+
+#define KERNEL_IMAGE_SIZE      (512 * 1024 * 1024)
+#define __START_KERNEL         0x100000
+#define __NO_KASLR_START_KERNEL        CONFIG_KERNEL_IMAGE_BASE
+#define __NO_KASLR_END_KERNEL  (__NO_KASLR_START_KERNEL + KERNEL_IMAGE_SIZE)
+
 #endif /* _S390_PAGE_H */
index 60950e7a25f585b5b2d0f0bf8ce0fff9c91b475c..6f11d063d54500352154ff77db5ad3dd4b374c23 100644 (file)
@@ -107,6 +107,12 @@ static inline int is_module_addr(void *addr)
        return 1;
 }
 
+#ifdef CONFIG_RANDOMIZE_BASE
+#define KASLR_LEN      (1UL << 31)
+#else
+#define KASLR_LEN      0UL
+#endif
+
 /*
  * A 64 bit pagetable entry of S390 has following format:
  * |                    PFRA                         |0IPC|  OS  |
@@ -566,10 +572,20 @@ static inline pud_t set_pud_bit(pud_t pud, pgprot_t prot)
 }
 
 /*
- * In the case that a guest uses storage keys
- * faults should no longer be backed by zero pages
+ * As soon as the guest uses storage keys or enables PV, we deduplicate all
+ * mapped shared zeropages and prevent new shared zeropages from getting
+ * mapped.
  */
-#define mm_forbids_zeropage mm_has_pgste
+#define mm_forbids_zeropage mm_forbids_zeropage
+static inline int mm_forbids_zeropage(struct mm_struct *mm)
+{
+#ifdef CONFIG_PGSTE
+       if (!mm->context.allow_cow_sharing)
+               return 1;
+#endif
+       return 0;
+}
+
 static inline int mm_uses_skeys(struct mm_struct *mm)
 {
 #ifdef CONFIG_PGSTE
index e747b067f8dbbf34c7ee0e3922c82325838d2a43..f45cfc8bc233ffd16cada4d04aa78000469bcfe4 100644 (file)
@@ -22,7 +22,6 @@ enum reserved_range_type {
        RR_DECOMPRESSOR,
        RR_INITRD,
        RR_VMLINUX,
-       RR_RELOC,
        RR_AMODE31,
        RR_IPLREPORT,
        RR_CERT_COMP_LIST,
@@ -170,4 +169,7 @@ static inline unsigned long get_physmem_reserved(enum reserved_range_type type,
        return *size;
 }
 
+#define AMODE31_START  (physmem_info.reserved[RR_AMODE31].start)
+#define AMODE31_END    (physmem_info.reserved[RR_AMODE31].end)
+
 #endif
index 03bcaa8effb2222e4d88d2cda14cae6c861df113..32f70873e2b7d5bc31e48b0ce24da5e965e26dfe 100644 (file)
@@ -127,20 +127,6 @@ extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
 extern void (*_machine_power_off)(void);
 
-extern unsigned long __kaslr_offset;
-static inline unsigned long kaslr_offset(void)
-{
-       return __kaslr_offset;
-}
-
-extern int __kaslr_enabled;
-static inline int kaslr_enabled(void)
-{
-       if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
-               return __kaslr_enabled;
-       return 0;
-}
-
 struct oldmem_data {
        unsigned long start;
        unsigned long size;
index fa029d0dc28ff90567a47ec2ff264198c1342890..db2d9ba5a86d229a91a9ff375c70a2edc0b9ed26 100644 (file)
@@ -11,6 +11,8 @@ CFLAGS_REMOVE_ftrace.o                = $(CC_FLAGS_FTRACE)
 # Do not trace early setup code
 CFLAGS_REMOVE_early.o          = $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_rethook.o                = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_stacktrace.o     = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_unwind_bc.o      = $(CC_FLAGS_FTRACE)
 
 endif
 
index d09ebb6f52625ef6b5021131cc18faedc75ca374..9863ebe75019a6daf28596e3274a7e51437f2c80 100644 (file)
@@ -465,7 +465,11 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt)
        ehdr->e_phoff = sizeof(Elf64_Ehdr);
        ehdr->e_ehsize = sizeof(Elf64_Ehdr);
        ehdr->e_phentsize = sizeof(Elf64_Phdr);
-       ehdr->e_phnum = mem_chunk_cnt + 1;
+       /*
+        * Number of memory chunk PT_LOAD program headers plus one kernel
+        * image PT_LOAD program header plus one PT_NOTE program header.
+        */
+       ehdr->e_phnum = mem_chunk_cnt + 1 + 1;
        return ehdr + 1;
 }
 
@@ -501,15 +505,16 @@ static int get_mem_chunk_cnt(void)
  */
 static void loads_init(Elf64_Phdr *phdr)
 {
+       unsigned long old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE);
        phys_addr_t start, end;
        u64 idx;
 
        for_each_physmem_range(idx, &oldmem_type, &start, &end) {
-               phdr->p_filesz = end - start;
                phdr->p_type = PT_LOAD;
+               phdr->p_vaddr = old_identity_base + start;
                phdr->p_offset = start;
-               phdr->p_vaddr = (unsigned long)__va(start);
                phdr->p_paddr = start;
+               phdr->p_filesz = end - start;
                phdr->p_memsz = end - start;
                phdr->p_flags = PF_R | PF_W | PF_X;
                phdr->p_align = PAGE_SIZE;
@@ -517,6 +522,25 @@ static void loads_init(Elf64_Phdr *phdr)
        }
 }
 
+/*
+ * Prepare PT_LOAD type program header for kernel image region
+ */
+static void text_init(Elf64_Phdr *phdr)
+{
+       unsigned long start_phys = os_info_old_value(OS_INFO_IMAGE_PHYS);
+       unsigned long start = os_info_old_value(OS_INFO_IMAGE_START);
+       unsigned long end = os_info_old_value(OS_INFO_IMAGE_END);
+
+       phdr->p_type = PT_LOAD;
+       phdr->p_vaddr = start;
+       phdr->p_filesz = end - start;
+       phdr->p_memsz = end - start;
+       phdr->p_offset = start_phys;
+       phdr->p_paddr = start_phys;
+       phdr->p_flags = PF_R | PF_W | PF_X;
+       phdr->p_align = PAGE_SIZE;
+}
+
 /*
  * Initialize notes (new kernel)
  */
@@ -557,6 +581,8 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
        size += nt_vmcoreinfo_size();
        /* nt_final */
        size += sizeof(Elf64_Nhdr);
+       /* PT_LOAD type program header for kernel text region */
+       size += sizeof(Elf64_Phdr);
        /* PT_LOADS */
        size += mem_chunk_cnt * sizeof(Elf64_Phdr);
 
@@ -568,7 +594,7 @@ static size_t get_elfcorehdr_size(int mem_chunk_cnt)
  */
 int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
 {
-       Elf64_Phdr *phdr_notes, *phdr_loads;
+       Elf64_Phdr *phdr_notes, *phdr_loads, *phdr_text;
        size_t alloc_size;
        int mem_chunk_cnt;
        void *ptr, *hdr;
@@ -606,14 +632,19 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
        /* Init program headers */
        phdr_notes = ptr;
        ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
+       phdr_text = ptr;
+       ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr));
        phdr_loads = ptr;
        ptr = PTR_ADD(ptr, sizeof(Elf64_Phdr) * mem_chunk_cnt);
        /* Init notes */
        hdr_off = PTR_DIFF(ptr, hdr);
        ptr = notes_init(phdr_notes, ptr, ((unsigned long) hdr) + hdr_off);
+       /* Init kernel text program header */
+       text_init(phdr_text);
        /* Init loads */
-       hdr_off = PTR_DIFF(ptr, hdr);
        loads_init(phdr_loads);
+       /* Finalize program headers */
+       hdr_off = PTR_DIFF(ptr, hdr);
        *addr = (unsigned long long) hdr;
        *size = (unsigned long long) hdr_off;
        BUG_ON(elfcorehdr_size > alloc_size);
index 1486350a417751736b9bc934bd424fa9efc3de15..7dc54571f18eeacd496d89a0d004659341785741 100644 (file)
@@ -1209,8 +1209,8 @@ static struct attribute_group reipl_nss_attr_group = {
 
 void set_os_info_reipl_block(void)
 {
-       os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
-                         reipl_block_actual->hdr.len);
+       os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
+                              reipl_block_actual->hdr.len);
 }
 
 /* reipl type */
@@ -1940,7 +1940,7 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
            reipl_type == IPL_TYPE_NSS ||
            reipl_type == IPL_TYPE_UNKNOWN)
                os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
-       os_info_entry_add(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
+       os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
        csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
        abs_lc = get_abs_lowcore();
        abs_lc->ipib = __pa(reipl_block_actual);
index d1b16d83e49ade48ada34328b70c926748041812..9b8c24ebb00858561df634ac3a17124d53bc92e9 100644 (file)
@@ -114,10 +114,10 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
                        type = BRASL_EXPOLINE;  /* brasl instruction */
                else
                        continue;
-               thunk = instr + (*(int *)(instr + 2)) * 2;
+               thunk = instr + (long)(*(int *)(instr + 2)) * 2;
                if (thunk[0] == 0xc6 && thunk[1] == 0x00)
                        /* exrl %r0,<target-br> */
-                       br = thunk + (*(int *)(thunk + 2)) * 2;
+                       br = thunk + (long)(*(int *)(thunk + 2)) * 2;
                else
                        continue;
                if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0)
index a801e6bd534178ce04bf161e3f2ff6e954d75e91..b695f980bbde030806925e6fce10969a69651ee5 100644 (file)
 #include <asm/checksum.h>
 #include <asm/abs_lowcore.h>
 #include <asm/os_info.h>
+#include <asm/physmem_info.h>
 #include <asm/maccess.h>
 #include <asm/asm-offsets.h>
+#include <asm/ipl.h>
 
 /*
  * OS info structure has to be page aligned
@@ -43,9 +45,9 @@ void os_info_crashkernel_add(unsigned long base, unsigned long size)
 }
 
 /*
- * Add OS info entry and update checksum
+ * Add OS info data entry and update checksum
  */
-void os_info_entry_add(int nr, void *ptr, u64 size)
+void os_info_entry_add_data(int nr, void *ptr, u64 size)
 {
        os_info.entry[nr].addr = __pa(ptr);
        os_info.entry[nr].size = size;
@@ -53,6 +55,17 @@ void os_info_entry_add(int nr, void *ptr, u64 size)
        os_info.csum = os_info_csum(&os_info);
 }
 
+/*
+ * Add OS info value entry and update checksum
+ */
+void os_info_entry_add_val(int nr, u64 value)
+{
+       os_info.entry[nr].val = value;
+       os_info.entry[nr].size = 0;
+       os_info.entry[nr].csum = 0;
+       os_info.csum = os_info_csum(&os_info);
+}
+
 /*
  * Initialize OS info structure and set lowcore pointer
  */
@@ -60,9 +73,19 @@ void __init os_info_init(void)
 {
        struct lowcore *abs_lc;
 
+       BUILD_BUG_ON(sizeof(struct os_info) != PAGE_SIZE);
        os_info.version_major = OS_INFO_VERSION_MAJOR;
        os_info.version_minor = OS_INFO_VERSION_MINOR;
        os_info.magic = OS_INFO_MAGIC;
+       os_info_entry_add_val(OS_INFO_IDENTITY_BASE, __identity_base);
+       os_info_entry_add_val(OS_INFO_KASLR_OFFSET, kaslr_offset());
+       os_info_entry_add_val(OS_INFO_KASLR_OFF_PHYS, __kaslr_offset_phys);
+       os_info_entry_add_val(OS_INFO_VMEMMAP, (unsigned long)vmemmap);
+       os_info_entry_add_val(OS_INFO_AMODE31_START, AMODE31_START);
+       os_info_entry_add_val(OS_INFO_AMODE31_END, AMODE31_END);
+       os_info_entry_add_val(OS_INFO_IMAGE_START, (unsigned long)_stext);
+       os_info_entry_add_val(OS_INFO_IMAGE_END, (unsigned long)_end);
+       os_info_entry_add_val(OS_INFO_IMAGE_PHYS, __pa_symbol(_stext));
        os_info.csum = os_info_csum(&os_info);
        abs_lc = get_abs_lowcore();
        abs_lc->os_info = __pa(&os_info);
@@ -125,7 +148,7 @@ static void os_info_old_init(void)
 
        if (os_info_init)
                return;
-       if (!oldmem_data.start)
+       if (!oldmem_data.start && !is_ipl_type_dump())
                goto fail;
        if (copy_oldmem_kernel(&addr, __LC_OS_INFO, sizeof(addr)))
                goto fail;
index 41ed6e0f0a2a927858bede1732af81493fc23086..1434642e9cba0d5c35bda8e77cc292d1cf64df20 100644 (file)
@@ -428,7 +428,7 @@ static void cpum_cf_make_setsize(enum cpumf_ctr_set ctrset)
        case CPUMF_CTR_SET_CRYPTO:
                if (cpumf_ctr_info.csvn >= 1 && cpumf_ctr_info.csvn <= 5)
                        ctrset_size = 16;
-               else if (cpumf_ctr_info.csvn == 6 || cpumf_ctr_info.csvn == 7)
+               else if (cpumf_ctr_info.csvn >= 6)
                        ctrset_size = 20;
                break;
        case CPUMF_CTR_SET_EXT:
index 0d64aafd158f2256bc60c570e557ef1735baf053..e4a6bfc910808a9ef98a208cff2f24f75eaf60ed 100644 (file)
@@ -855,16 +855,11 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
        }
 
        /* Determine version specific crypto set */
-       switch (ci.csvn) {
-       case 1 ... 5:
+       csvn = none;
+       if (ci.csvn >= 1 && ci.csvn <= 5)
                csvn = cpumcf_svn_12345_pmu_event_attr;
-               break;
-       case 6 ... 7:
+       else if (ci.csvn >= 6)
                csvn = cpumcf_svn_67_pmu_event_attr;
-               break;
-       default:
-               csvn = none;
-       }
 
        /* Determine model-specific counter set(s) */
        get_cpu_id(&cpu_id);
index 24ed33f044ec39720b11f83a5a925303d8c983a2..cbd5290939df1cb81cb8528543255d8245224a56 100644 (file)
@@ -146,10 +146,10 @@ static u32 __amode31_ref *__ctl_linkage_stack = __ctl_linkage_stack_amode31;
 static u32 __amode31_ref *__ctl_duct = __ctl_duct_amode31;
 
 unsigned long __bootdata_preserved(max_mappable);
-unsigned long __bootdata(ident_map_size);
 struct physmem_info __bootdata(physmem_info);
 
-unsigned long __bootdata_preserved(__kaslr_offset);
+struct vm_layout __bootdata_preserved(vm_layout);
+EXPORT_SYMBOL_GPL(vm_layout);
 int __bootdata_preserved(__kaslr_enabled);
 unsigned int __bootdata_preserved(zlib_dfltcc_support);
 EXPORT_SYMBOL(zlib_dfltcc_support);
@@ -765,7 +765,7 @@ static void __init relocate_amode31_section(void)
        unsigned long amode31_size = __eamode31 - __samode31;
        long amode31_offset, *ptr;
 
-       amode31_offset = physmem_info.reserved[RR_AMODE31].start - (unsigned long)__samode31;
+       amode31_offset = AMODE31_START - (unsigned long)__samode31;
        pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
 
        /* Move original AMODE31 section to the new one */
index 94f440e38303191d64097f12a274cb46e5a10e2e..7c294da45bf524e9891d8c3e83ab71f9b0115e50 100644 (file)
@@ -101,3 +101,22 @@ void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
        }
        pagefault_enable();
 }
+
+unsigned long return_address(unsigned int n)
+{
+       struct unwind_state state;
+       unsigned long addr;
+
+       /* Increment to skip current stack entry */
+       n++;
+
+       unwind_for_each_frame(&state, NULL, NULL, 0) {
+               addr = unwind_get_return_address(&state);
+               if (!addr)
+                       break;
+               if (!n--)
+                       return addr;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(return_address);
index fc07bc39e69839698e2ca4a9db424b9d0fe70aba..265fea37e0308c3464d81e81eea47f1731f7dfde 100644 (file)
@@ -21,6 +21,7 @@
 /* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */
 #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST
 int __bootdata_preserved(prot_virt_guest);
+EXPORT_SYMBOL(prot_virt_guest);
 #endif
 
 /*
@@ -181,36 +182,36 @@ int uv_convert_owned_from_secure(unsigned long paddr)
 }
 
 /*
- * Calculate the expected ref_count for a page that would otherwise have no
+ * Calculate the expected ref_count for a folio that would otherwise have no
  * further pins. This was cribbed from similar functions in other places in
  * the kernel, but with some slight modifications. We know that a secure
- * page can not be a huge page for example.
+ * folio can not be a large folio, for example.
  */
-static int expected_page_refs(struct page *page)
+static int expected_folio_refs(struct folio *folio)
 {
        int res;
 
-       res = page_mapcount(page);
-       if (PageSwapCache(page)) {
+       res = folio_mapcount(folio);
+       if (folio_test_swapcache(folio)) {
                res++;
-       } else if (page_mapping(page)) {
+       } else if (folio_mapping(folio)) {
                res++;
-               if (page_has_private(page))
+               if (folio->private)
                        res++;
        }
        return res;
 }
 
-static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
+static int make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb)
 {
        int expected, cc = 0;
 
-       if (PageWriteback(page))
+       if (folio_test_writeback(folio))
                return -EAGAIN;
-       expected = expected_page_refs(page);
-       if (!page_ref_freeze(page, expected))
+       expected = expected_folio_refs(folio);
+       if (!folio_ref_freeze(folio, expected))
                return -EBUSY;
-       set_bit(PG_arch_1, &page->flags);
+       set_bit(PG_arch_1, &folio->flags);
        /*
         * If the UVC does not succeed or fail immediately, we don't want to
         * loop for long, or we might get stall notifications.
@@ -220,9 +221,9 @@ static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
         * -EAGAIN and we let the callers deal with it.
         */
        cc = __uv_call(0, (u64)uvcb);
-       page_ref_unfreeze(page, expected);
+       folio_ref_unfreeze(folio, expected);
        /*
-        * Return -ENXIO if the page was not mapped, -EINVAL for other errors.
+        * Return -ENXIO if the folio was not mapped, -EINVAL for other errors.
         * If busy or partially completed, return -EAGAIN.
         */
        if (cc == UVC_CC_OK)
@@ -277,7 +278,7 @@ int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb)
        bool local_drain = false;
        spinlock_t *ptelock;
        unsigned long uaddr;
-       struct page *page;
+       struct folio *folio;
        pte_t *ptep;
        int rc;
 
@@ -306,15 +307,19 @@ again:
        if (!ptep)
                goto out;
        if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) {
-               page = pte_page(*ptep);
+               folio = page_folio(pte_page(*ptep));
+               rc = -EINVAL;
+               if (folio_test_large(folio))
+                       goto unlock;
                rc = -EAGAIN;
-               if (trylock_page(page)) {
+               if (folio_trylock(folio)) {
                        if (should_export_before_import(uvcb, gmap->mm))
-                               uv_convert_from_secure(page_to_phys(page));
-                       rc = make_page_secure(page, uvcb);
-                       unlock_page(page);
+                               uv_convert_from_secure(PFN_PHYS(folio_pfn(folio)));
+                       rc = make_folio_secure(folio, uvcb);
+                       folio_unlock(folio);
                }
        }
+unlock:
        pte_unmap_unlock(ptep, ptelock);
 out:
        mmap_read_unlock(gmap->mm);
@@ -324,10 +329,10 @@ out:
                 * If we are here because the UVC returned busy or partial
                 * completion, this is just a useless check, but it is safe.
                 */
-               wait_on_page_writeback(page);
+               folio_wait_writeback(folio);
        } else if (rc == -EBUSY) {
                /*
-                * If we have tried a local drain and the page refcount
+                * If we have tried a local drain and the folio refcount
                 * still does not match our expected safe value, try with a
                 * system wide drain. This is needed if the pagevecs holding
                 * the page are on a different CPU.
@@ -338,7 +343,7 @@ out:
                        return -EAGAIN;
                }
                /*
-                * We are here if the page refcount does not match the
+                * We are here if the folio refcount does not match the
                 * expected safe value. The main culprits are usually
                 * pagevecs. With lru_add_drain() we drain the pagevecs
                 * on the local CPU so that hopefully the refcount will
index 57f62596e53b958a2737f23f1985e5154179fd9e..85247ef5a41b89a390d3290cefb785c6c5a81ad6 100644 (file)
@@ -24,8 +24,10 @@ __kernel_\func:
        CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE)
        CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
        stg     %r14,STACK_FRAME_OVERHEAD(%r15)
+       CFI_REL_OFFSET 14, STACK_FRAME_OVERHEAD
        brasl   %r14,__s390_vdso_\func
        lg      %r14,STACK_FRAME_OVERHEAD(%r15)
+       CFI_RESTORE 14
        aghi    %r15,WRAPPER_FRAME_SIZE
        CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
        CFI_RESTORE 15
index d296dfc22191cac1739d7b6e602f9bd9fa51637f..23f7d7619a992efb26e4160fbe6551893b172691 100644 (file)
@@ -14,7 +14,9 @@ void arch_crash_save_vmcoreinfo(void)
        VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
        vmcoreinfo_append_str("SAMODE31=%lx\n", (unsigned long)__samode31);
        vmcoreinfo_append_str("EAMODE31=%lx\n", (unsigned long)__eamode31);
+       vmcoreinfo_append_str("IDENTITYBASE=%lx\n", __identity_base);
        vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+       vmcoreinfo_append_str("KERNELOFFPHYS=%lx\n", __kaslr_offset_phys);
        abs_lc = get_abs_lowcore();
        abs_lc->vmcore_info = paddr_vmcoreinfo_note();
        put_abs_lowcore(abs_lc);
index 48de296e8905c1bef0ad7059aa92666656adc8b1..a1ce3925ec719055d14dfbeb8e5eb63416bc2d31 100644 (file)
@@ -39,7 +39,7 @@ PHDRS {
 
 SECTIONS
 {
-       . = 0x100000;
+       . = __START_KERNEL;
        .text : {
                _stext = .;             /* Start of text section */
                _text = .;              /* Text and read-only data */
@@ -183,7 +183,7 @@ SECTIONS
        .amode31.data : {
                *(.amode31.data)
        }
-       . = ALIGN(PAGE_SIZE);
+       . = _samode31 + AMODE31_SIZE;
        _eamode31 = .;
 
        /* early.c uses stsi, which requires page aligned data. */
@@ -192,31 +192,6 @@ SECTIONS
 
        PERCPU_SECTION(0x100)
 
-#ifdef CONFIG_PIE_BUILD
-       .dynsym ALIGN(8) : {
-               __dynsym_start = .;
-               *(.dynsym)
-               __dynsym_end = .;
-       }
-       .rela.dyn ALIGN(8) : {
-               __rela_dyn_start = .;
-               *(.rela*)
-               __rela_dyn_end = .;
-       }
-       .dynamic ALIGN(8) : {
-               *(.dynamic)
-       }
-       .dynstr ALIGN(8) : {
-               *(.dynstr)
-       }
-#endif
-       .hash ALIGN(8) : {
-               *(.hash)
-       }
-       .gnu.hash ALIGN(8) : {
-               *(.gnu.hash)
-       }
-
        . = ALIGN(PAGE_SIZE);
        __init_end = .;         /* freed after init ends here */
 
@@ -230,7 +205,6 @@ SECTIONS
         * it should match struct vmlinux_info
         */
        .vmlinux.info 0 (INFO) : {
-               QUAD(_stext)                                    /* default_lma */
                QUAD(startup_continue)                          /* entry */
                QUAD(__bss_start - _stext)                      /* image_size */
                QUAD(__bss_stop - __bss_start)                  /* bss_size */
@@ -239,14 +213,8 @@ SECTIONS
                QUAD(__boot_data_preserved_start)               /* bootdata_preserved_off */
                QUAD(__boot_data_preserved_end -
                     __boot_data_preserved_start)               /* bootdata_preserved_size */
-#ifdef CONFIG_PIE_BUILD
-               QUAD(__dynsym_start)                            /* dynsym_start */
-               QUAD(__rela_dyn_start)                          /* rela_dyn_start */
-               QUAD(__rela_dyn_end)                            /* rela_dyn_end */
-#else
                QUAD(__got_start)                               /* got_start */
                QUAD(__got_end)                                 /* got_end */
-#endif
                QUAD(_eamode31 - _samode31)                     /* amode31_size */
                QUAD(init_mm)
                QUAD(swapper_pg_dir)
@@ -282,12 +250,10 @@ SECTIONS
                *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
        }
        ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
-#ifndef CONFIG_PIE_BUILD
        .rela.dyn : {
                *(.rela.*) *(.rela_*)
        }
        ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
-#endif
 
        /* Sections to be discarded */
        DISCARDS
index 5147b943a864a641fcf5d87fed39eb33f4590bea..82e9631cd9efb86defd13e029f0a737726ba853b 100644 (file)
@@ -587,7 +587,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                break;
        case KVM_CAP_S390_HPAGE_1M:
                r = 0;
-               if (hpage && !kvm_is_ucontrol(kvm))
+               if (hpage && !(kvm && kvm_is_ucontrol(kvm)))
                        r = 1;
                break;
        case KVM_CAP_S390_MEM_OP:
@@ -2631,9 +2631,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
                if (r)
                        break;
 
-               mmap_write_lock(current->mm);
-               r = gmap_mark_unmergeable();
-               mmap_write_unlock(current->mm);
+               r = s390_disable_cow_sharing();
                if (r)
                        break;
 
index b2c9f010f0fefd6744289d03a7f1e7c294b791e6..c9ecae830634f5f73863736c1e2137a7b08728e2 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/list.h>
 #include <linux/bitmap.h>
 #include <linux/sched/signal.h>
+#include <linux/io.h>
 
 #include <asm/gmap.h>
 #include <asm/mmu_context.h>
@@ -361,7 +362,7 @@ end:
        case -EACCES:
                return set_validity_icpt(scb_s, 0x003CU);
        }
-       scb_s->crycbd = ((__u32)(__u64) &vsie_page->crycb) | CRYCB_FORMAT2;
+       scb_s->crycbd = (u32)virt_to_phys(&vsie_page->crycb) | CRYCB_FORMAT2;
        return 0;
 }
 
@@ -1005,7 +1006,7 @@ static int handle_stfle(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
                if (read_guest_real(vcpu, fac, &vsie_page->fac,
                                    stfle_size() * sizeof(u64)))
                        return set_validity_icpt(scb_s, 0x1090U);
-               scb_s->fac = (__u32)(__u64) &vsie_page->fac;
+               scb_s->fac = (u32)virt_to_phys(&vsie_page->fac);
        }
        return 0;
 }
index 90eac15ea62aaf22b2984e09c7ce4a2b3bc6f504..f43f897d3fc027ad2f5cbf52ba2abc343b6e31ea 100644 (file)
@@ -23,4 +23,4 @@ obj-$(CONFIG_S390_MODULES_SANITY_TEST_HELPERS) += test_modules_helpers.o
 
 lib-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 
-obj-$(CONFIG_EXPOLINE_EXTERN) += expoline/
+obj-$(CONFIG_EXPOLINE_EXTERN) += expoline.o
diff --git a/arch/s390/lib/expoline/Makefile b/arch/s390/lib/expoline/Makefile
deleted file mode 100644 (file)
index 854631d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-obj-y += expoline.o
index 094b43b121cd5d8d8895af0f1c830ab5cfb1d355..474a25ca5c48ff41935a6ae23eeff29617b877ed 100644 (file)
@@ -2549,41 +2549,6 @@ static inline void thp_split_mm(struct mm_struct *mm)
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
-/*
- * Remove all empty zero pages from the mapping for lazy refaulting
- * - This must be called after mm->context.has_pgste is set, to avoid
- *   future creation of zero pages
- * - This must be called after THP was disabled.
- *
- * mm contracts with s390, that even if mm were to remove a page table,
- * racing with the loop below and so causing pte_offset_map_lock() to fail,
- * it will never insert a page table containing empty zero pages once
- * mm_forbids_zeropage(mm) i.e. mm->context.has_pgste is set.
- */
-static int __zap_zero_pages(pmd_t *pmd, unsigned long start,
-                          unsigned long end, struct mm_walk *walk)
-{
-       unsigned long addr;
-
-       for (addr = start; addr != end; addr += PAGE_SIZE) {
-               pte_t *ptep;
-               spinlock_t *ptl;
-
-               ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
-               if (!ptep)
-                       break;
-               if (is_zero_pfn(pte_pfn(*ptep)))
-                       ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID));
-               pte_unmap_unlock(ptep, ptl);
-       }
-       return 0;
-}
-
-static const struct mm_walk_ops zap_zero_walk_ops = {
-       .pmd_entry      = __zap_zero_pages,
-       .walk_lock      = PGWALK_WRLOCK,
-};
-
 /*
  * switch on pgstes for its userspace process (for kvm)
  */
@@ -2601,22 +2566,142 @@ int s390_enable_sie(void)
        mm->context.has_pgste = 1;
        /* split thp mappings and disable thp for future mappings */
        thp_split_mm(mm);
-       walk_page_range(mm, 0, TASK_SIZE, &zap_zero_walk_ops, NULL);
        mmap_write_unlock(mm);
        return 0;
 }
 EXPORT_SYMBOL_GPL(s390_enable_sie);
 
-int gmap_mark_unmergeable(void)
+static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr,
+                                  unsigned long end, struct mm_walk *walk)
+{
+       unsigned long *found_addr = walk->private;
+
+       /* Return 1 of the page is a zeropage. */
+       if (is_zero_pfn(pte_pfn(*pte))) {
+               /*
+                * Shared zeropage in e.g., a FS DAX mapping? We cannot do the
+                * right thing and likely don't care: FAULT_FLAG_UNSHARE
+                * currently only works in COW mappings, which is also where
+                * mm_forbids_zeropage() is checked.
+                */
+               if (!is_cow_mapping(walk->vma->vm_flags))
+                       return -EFAULT;
+
+               *found_addr = addr;
+               return 1;
+       }
+       return 0;
+}
+
+static const struct mm_walk_ops find_zeropage_ops = {
+       .pte_entry      = find_zeropage_pte_entry,
+       .walk_lock      = PGWALK_WRLOCK,
+};
+
+/*
+ * Unshare all shared zeropages, replacing them by anonymous pages. Note that
+ * we cannot simply zap all shared zeropages, because this could later
+ * trigger unexpected userfaultfd missing events.
+ *
+ * This must be called after mm->context.allow_cow_sharing was
+ * set to 0, to avoid future mappings of shared zeropages.
+ *
+ * mm contracts with s390, that even if mm were to remove a page table,
+ * and racing with walk_page_range_vma() calling pte_offset_map_lock()
+ * would fail, it will never insert a page table containing empty zero
+ * pages once mm_forbids_zeropage(mm) i.e.
+ * mm->context.allow_cow_sharing is set to 0.
+ */
+static int __s390_unshare_zeropages(struct mm_struct *mm)
+{
+       struct vm_area_struct *vma;
+       VMA_ITERATOR(vmi, mm, 0);
+       unsigned long addr;
+       vm_fault_t fault;
+       int rc;
+
+       for_each_vma(vmi, vma) {
+               /*
+                * We could only look at COW mappings, but it's more future
+                * proof to catch unexpected zeropages in other mappings and
+                * fail.
+                */
+               if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma))
+                       continue;
+               addr = vma->vm_start;
+
+retry:
+               rc = walk_page_range_vma(vma, addr, vma->vm_end,
+                                        &find_zeropage_ops, &addr);
+               if (rc < 0)
+                       return rc;
+               else if (!rc)
+                       continue;
+
+               /* addr was updated by find_zeropage_pte_entry() */
+               fault = handle_mm_fault(vma, addr,
+                                       FAULT_FLAG_UNSHARE | FAULT_FLAG_REMOTE,
+                                       NULL);
+               if (fault & VM_FAULT_OOM)
+                       return -ENOMEM;
+               /*
+                * See break_ksm(): even after handle_mm_fault() returned 0, we
+                * must start the lookup from the current address, because
+                * handle_mm_fault() may back out if there's any difficulty.
+                *
+                * VM_FAULT_SIGBUS and VM_FAULT_SIGSEGV are unexpected but
+                * maybe they could trigger in the future on concurrent
+                * truncation. In that case, the shared zeropage would be gone
+                * and we can simply retry and make progress.
+                */
+               cond_resched();
+               goto retry;
+       }
+
+       return 0;
+}
+
+static int __s390_disable_cow_sharing(struct mm_struct *mm)
 {
+       int rc;
+
+       if (!mm->context.allow_cow_sharing)
+               return 0;
+
+       mm->context.allow_cow_sharing = 0;
+
+       /* Replace all shared zeropages by anonymous pages. */
+       rc = __s390_unshare_zeropages(mm);
        /*
         * Make sure to disable KSM (if enabled for the whole process or
         * individual VMAs). Note that nothing currently hinders user space
         * from re-enabling it.
         */
-       return ksm_disable(current->mm);
+       if (!rc)
+               rc = ksm_disable(mm);
+       if (rc)
+               mm->context.allow_cow_sharing = 1;
+       return rc;
+}
+
+/*
+ * Disable most COW-sharing of memory pages for the whole process:
+ * (1) Disable KSM and unmerge/unshare any KSM pages.
+ * (2) Disallow shared zeropages and unshare any zerpages that are mapped.
+ *
+ * Not that we currently don't bother with COW-shared pages that are shared
+ * with parent/child processes due to fork().
+ */
+int s390_disable_cow_sharing(void)
+{
+       int rc;
+
+       mmap_write_lock(current->mm);
+       rc = __s390_disable_cow_sharing(current->mm);
+       mmap_write_unlock(current->mm);
+       return rc;
 }
-EXPORT_SYMBOL_GPL(gmap_mark_unmergeable);
+EXPORT_SYMBOL_GPL(s390_disable_cow_sharing);
 
 /*
  * Enable storage key handling from now on and initialize the storage
@@ -2661,7 +2746,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
                return 0;
 
        start = pmd_val(*pmd) & HPAGE_MASK;
-       end = start + HPAGE_SIZE - 1;
+       end = start + HPAGE_SIZE;
        __storage_key_init_range(start, end);
        set_bit(PG_arch_1, &page->flags);
        cond_resched();
@@ -2685,7 +2770,7 @@ int s390_enable_skey(void)
                goto out_up;
 
        mm->context.uses_skeys = 1;
-       rc = gmap_mark_unmergeable();
+       rc = __s390_disable_cow_sharing(mm);
        if (rc) {
                mm->context.uses_skeys = 0;
                goto out_up;
index c2e8242bd15dd0afb6454e9e71e9ca5ef969ba13..dc3db86e13ffb8c14ca607c6df86ede9d3cf6262 100644 (file)
@@ -139,7 +139,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
        }
 
        if (!test_and_set_bit(PG_arch_1, &page->flags))
-               __storage_key_init_range(paddr, paddr + size - 1);
+               __storage_key_init_range(paddr, paddr + size);
 }
 
 void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
index 85cddf904cb209ff265b6a6dcf115bd13d6f16c4..41c714e212927b12dad4aceba5c73b49169531e3 100644 (file)
@@ -13,7 +13,9 @@
 #include <linux/slab.h>
 #include <linux/sort.h>
 #include <asm/page-states.h>
+#include <asm/abs_lowcore.h>
 #include <asm/cacheflush.h>
+#include <asm/maccess.h>
 #include <asm/nospec-branch.h>
 #include <asm/ctlreg.h>
 #include <asm/pgalloc.h>
@@ -21,6 +23,7 @@
 #include <asm/tlbflush.h>
 #include <asm/sections.h>
 #include <asm/set_memory.h>
+#include <asm/physmem_info.h>
 
 static DEFINE_MUTEX(vmem_mutex);
 
@@ -436,7 +439,7 @@ static int modify_pagetable(unsigned long start, unsigned long end, bool add,
        if (WARN_ON_ONCE(!PAGE_ALIGNED(start | end)))
                return -EINVAL;
        /* Don't mess with any tables not fully in 1:1 mapping & vmemmap area */
-       if (WARN_ON_ONCE(end > VMALLOC_START))
+       if (WARN_ON_ONCE(end > __abs_lowcore))
                return -EINVAL;
        for (addr = start; addr < end; addr = next) {
                next = pgd_addr_end(addr, end);
index a0b872b74fe39af3cdf5a58f2fbbca01f516235c..0f4f1e8fc480dc0f0e5a35f1be1000e675f5f47a 100644 (file)
@@ -172,7 +172,6 @@ static ssize_t uid_is_unique_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(uid_is_unique);
 
-#ifndef CONFIG_DMI
 /* analogous to smbios index */
 static ssize_t index_show(struct device *dev,
                          struct device_attribute *attr, char *buf)
@@ -202,7 +201,6 @@ static struct attribute_group zpci_ident_attr_group = {
        .attrs = zpci_ident_attrs,
        .is_visible = zpci_index_is_visible,
 };
-#endif
 
 static struct bin_attribute *zpci_bin_attrs[] = {
        &bin_attr_util_string,
@@ -245,8 +243,6 @@ static struct attribute_group pfip_attr_group = {
 const struct attribute_group *zpci_attr_groups[] = {
        &zpci_attr_group,
        &pfip_attr_group,
-#ifndef CONFIG_DMI
        &zpci_ident_attr_group,
-#endif
        NULL,
 };
index 30a732c808f35e837145f692f77f07b122b40dd8..a74dbd5c9896a7b3fe30c104e2b662624dd0b26c 100644 (file)
@@ -280,7 +280,7 @@ static int do_reloc(struct section *sec, Elf_Rel *rel)
        case R_390_GOTOFF64:
                break;
        case R_390_64:
-               add_reloc(&relocs64, offset);
+               add_reloc(&relocs64, offset - ehdr.e_entry);
                break;
        default:
                die("Unsupported relocation type: %d\n", r_type);
index d0af82c240b7318fcde01a6fe613d6a611fe4540..8c1a3ca34eeb7aeb0d8cba1bf5de0c3c44d86673 100644 (file)
@@ -38,21 +38,19 @@ static __always_inline unsigned long __arch_xchg(unsigned long x, __volatile__ v
 
 /* bug catcher for when unsupported size is used - won't link */
 void __cmpxchg_called_with_bad_pointer(void);
-/* we only need to support cmpxchg of a u32 on sparc */
-unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
+u8 __cmpxchg_u8(volatile u8 *m, u8 old, u8 new_);
+u16 __cmpxchg_u16(volatile u16 *m, u16 old, u16 new_);
+u32 __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
 
 /* don't worry...optimizer will get rid of most of this */
 static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
 {
-       switch (size) {
-       case 4:
-               return __cmpxchg_u32((u32 *)ptr, (u32)old, (u32)new_);
-       default:
-               __cmpxchg_called_with_bad_pointer();
-               break;
-       }
-       return old;
+       return
+               size == 1 ? __cmpxchg_u8(ptr, old, new_) :
+               size == 2 ? __cmpxchg_u16(ptr, old, new_) :
+               size == 4 ? __cmpxchg_u32(ptr, old, new_) :
+                       (__cmpxchg_called_with_bad_pointer(), old);
 }
 
 #define arch_cmpxchg(ptr, o, n)                                                \
@@ -63,7 +61,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
                        (unsigned long)_n_, sizeof(*(ptr)));            \
 })
 
-u64 __cmpxchg_u64(u64 *ptr, u64 old, u64 new);
+u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new);
 #define arch_cmpxchg64(ptr, old, new)  __cmpxchg_u64(ptr, old, new)
 
 #include <asm-generic/cmpxchg-local.h>
index cf80d1ae352be668b8e87ac5baa7595537c5f60b..8ae880ebf07aac2e6748c86858e3eb7003058948 100644 (file)
@@ -159,32 +159,27 @@ unsigned long sp32___change_bit(unsigned long *addr, unsigned long mask)
 }
 EXPORT_SYMBOL(sp32___change_bit);
 
-unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new)
-{
-       unsigned long flags;
-       u32 prev;
-
-       spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
-       if ((prev = *ptr) == old)
-               *ptr = new;
-       spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
-
-       return (unsigned long)prev;
-}
+#define CMPXCHG(T)                                             \
+       T __cmpxchg_##T(volatile T *ptr, T old, T new)          \
+       {                                                       \
+               unsigned long flags;                            \
+               T prev;                                         \
+                                                               \
+               spin_lock_irqsave(ATOMIC_HASH(ptr), flags);     \
+               if ((prev = *ptr) == old)                       \
+                       *ptr = new;                             \
+               spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);\
+                                                               \
+               return prev;                                    \
+       }
+
+CMPXCHG(u8)
+CMPXCHG(u16)
+CMPXCHG(u32)
+CMPXCHG(u64)
+EXPORT_SYMBOL(__cmpxchg_u8);
+EXPORT_SYMBOL(__cmpxchg_u16);
 EXPORT_SYMBOL(__cmpxchg_u32);
-
-u64 __cmpxchg_u64(u64 *ptr, u64 old, u64 new)
-{
-       unsigned long flags;
-       u64 prev;
-
-       spin_lock_irqsave(ATOMIC_HASH(ptr), flags);
-       if ((prev = *ptr) == old)
-               *ptr = new;
-       spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags);
-
-       return prev;
-}
 EXPORT_SYMBOL(__cmpxchg_u64);
 
 unsigned long __xchg_u32(volatile u32 *ptr, u32 new)
index 4474bf32d0a4970daec7fad3f12f8aa4a9e43871..928820e61cb5020a1eeb3bcc99b0a72227ae6c82 100644 (file)
@@ -62,6 +62,7 @@ config X86
        select ACPI_HOTPLUG_CPU                 if ACPI_PROCESSOR && HOTPLUG_CPU
        select ARCH_32BIT_OFF_T                 if X86_32
        select ARCH_CLOCKSOURCE_INIT
+       select ARCH_CONFIGURES_CPU_MITIGATIONS
        select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
        select ARCH_ENABLE_HUGEPAGE_MIGRATION if X86_64 && HUGETLB_PAGE && MIGRATION
        select ARCH_ENABLE_MEMORY_HOTPLUG if X86_64
@@ -2488,17 +2489,21 @@ config PREFIX_SYMBOLS
        def_bool y
        depends on CALL_PADDING && !CFI_CLANG
 
-menuconfig SPECULATION_MITIGATIONS
-       bool "Mitigations for speculative execution vulnerabilities"
+menuconfig CPU_MITIGATIONS
+       bool "Mitigations for CPU vulnerabilities"
        default y
        help
-         Say Y here to enable options which enable mitigations for
-         speculative execution hardware vulnerabilities.
+         Say Y here to enable options which enable mitigations for hardware
+         vulnerabilities (usually related to speculative execution).
+         Mitigations can be disabled or restricted to SMT systems at runtime
+         via the "mitigations" kernel parameter.
 
-         If you say N, all mitigations will be disabled. You really
-         should know what you are doing to say so.
+         If you say N, all mitigations will be disabled.  This CANNOT be
+         overridden at runtime.
 
-if SPECULATION_MITIGATIONS
+         Say 'Y', unless you really know what you are doing.
+
+if CPU_MITIGATIONS
 
 config MITIGATION_PAGE_TABLE_ISOLATION
        bool "Remove the kernel mapping in user mode"
index a3c0df11d0e6d8c36db77b59077fef711724b2db..2fb7d53cf3338d3c390fa1fe2f000cc622b3af03 100644 (file)
@@ -98,11 +98,6 @@ static int addr_to_vsyscall_nr(unsigned long addr)
 
 static bool write_ok_or_segv(unsigned long ptr, size_t size)
 {
-       /*
-        * XXX: if access_ok, get_user, and put_user handled
-        * sig_on_uaccess_err, this could go away.
-        */
-
        if (!access_ok((void __user *)ptr, size)) {
                struct thread_struct *thread = &current->thread;
 
@@ -120,10 +115,8 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size)
 bool emulate_vsyscall(unsigned long error_code,
                      struct pt_regs *regs, unsigned long address)
 {
-       struct task_struct *tsk;
        unsigned long caller;
        int vsyscall_nr, syscall_nr, tmp;
-       int prev_sig_on_uaccess_err;
        long ret;
        unsigned long orig_dx;
 
@@ -172,8 +165,6 @@ bool emulate_vsyscall(unsigned long error_code,
                goto sigsegv;
        }
 
-       tsk = current;
-
        /*
         * Check for access_ok violations and find the syscall nr.
         *
@@ -234,12 +225,8 @@ bool emulate_vsyscall(unsigned long error_code,
                goto do_ret;  /* skip requested */
 
        /*
-        * With a real vsyscall, page faults cause SIGSEGV.  We want to
-        * preserve that behavior to make writing exploits harder.
+        * With a real vsyscall, page faults cause SIGSEGV.
         */
-       prev_sig_on_uaccess_err = current->thread.sig_on_uaccess_err;
-       current->thread.sig_on_uaccess_err = 1;
-
        ret = -EFAULT;
        switch (vsyscall_nr) {
        case 0:
@@ -262,23 +249,12 @@ bool emulate_vsyscall(unsigned long error_code,
                break;
        }
 
-       current->thread.sig_on_uaccess_err = prev_sig_on_uaccess_err;
-
 check_fault:
        if (ret == -EFAULT) {
                /* Bad news -- userspace fed a bad pointer to a vsyscall. */
                warn_bad_vsyscall(KERN_INFO, regs,
                                  "vsyscall fault (exploit attempt?)");
-
-               /*
-                * If we failed to generate a signal for any reason,
-                * generate one here.  (This should be impossible.)
-                */
-               if (WARN_ON_ONCE(!sigismember(&tsk->pending.signal, SIGBUS) &&
-                                !sigismember(&tsk->pending.signal, SIGSEGV)))
-                       goto sigsegv;
-
-               return true;  /* Don't emulate the ret. */
+               goto sigsegv;
        }
 
        regs->ax = ret;
index c086699b0d0c59fc62834bb457963f1b81b541d3..aa6c8f8ca9588e90894750ce4f93226c05af9c23 100644 (file)
@@ -25,6 +25,7 @@ u64 cc_mkdec(u64 val);
 void cc_random_init(void);
 #else
 #define cc_vendor (CC_VENDOR_NONE)
+static const u64 cc_mask = 0;
 
 static inline u64 cc_mkenc(u64 val)
 {
index e8f58ddd06d97fbce6ef1f701f9f91766ef2847d..2e74a7f0e93575c3aa4180dc9ad4a9728f07700d 100644 (file)
@@ -17,6 +17,7 @@ extern bool e820__mapped_all(u64 start, u64 end, enum e820_type type);
 extern void e820__range_add   (u64 start, u64 size, enum e820_type type);
 extern u64  e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type);
 extern u64  e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type);
+extern u64  e820__range_update_table(struct e820_table *t, u64 start, u64 size, enum e820_type old_type, enum e820_type new_type);
 
 extern void e820__print_table(char *who);
 extern int  e820__update_table(struct e820_table *table);
index 0b748ee16b3d94ea09516ee14e187dbebae0bf4a..9abb8cc4cd4747f4982655d425df997852b1553b 100644 (file)
 #define _COMMON_PAGE_CHG_MASK  (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \
                                 _PAGE_SPECIAL | _PAGE_ACCESSED |       \
                                 _PAGE_DIRTY_BITS | _PAGE_SOFT_DIRTY |  \
-                                _PAGE_DEVMAP | _PAGE_ENC | _PAGE_UFFD_WP)
+                                _PAGE_DEVMAP | _PAGE_CC | _PAGE_UFFD_WP)
 #define _PAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PAT)
 #define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE)
 
@@ -173,6 +173,7 @@ enum page_cache_mode {
 };
 #endif
 
+#define _PAGE_CC               (_AT(pteval_t, cc_mask))
 #define _PAGE_ENC              (_AT(pteval_t, sme_me_mask))
 
 #define _PAGE_CACHE_MASK       (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)
index 811548f131f4e30418bedfdf98f1f302fc06723d..78e51b0d6433d6685c725b558bdd578c8ca4d6e8 100644 (file)
@@ -472,7 +472,6 @@ struct thread_struct {
        unsigned long           iopl_emul;
 
        unsigned int            iopl_warn:1;
-       unsigned int            sig_on_uaccess_err:1;
 
        /*
         * Protection Keys Register for Userspace.  Loaded immediately on
index 7f57382afee41754beb8164244f199e4ac30a148..93ed60080cfe7b58dc0349ab34fdb7e5704abd81 100644 (file)
@@ -269,6 +269,7 @@ int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 asid, bool immut
 int rmp_make_shared(u64 pfn, enum pg_level level);
 void snp_leak_pages(u64 pfn, unsigned int npages);
 void kdump_sev_callback(void);
+void snp_fixup_e820_tables(void);
 #else
 static inline bool snp_probe_rmptable_info(void) { return false; }
 static inline int snp_lookup_rmpentry(u64 pfn, bool *assigned, int *level) { return -ENODEV; }
@@ -282,6 +283,7 @@ static inline int rmp_make_private(u64 pfn, u64 gpa, enum pg_level level, u32 as
 static inline int rmp_make_shared(u64 pfn, enum pg_level level) { return -ENODEV; }
 static inline void snp_leak_pages(u64 pfn, unsigned int npages) {}
 static inline void kdump_sev_callback(void) { }
+static inline void snp_fixup_e820_tables(void) {}
 #endif
 
 #endif
index 5bf5f9fc5753a194fcc071b57af6184ad275a634..3cf156f7085917b8e1de4bec7d46b70b2998e1d6 100644 (file)
@@ -95,6 +95,7 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) },
        {}
index c342c4aa9c6848c607238dad1ff07105737d5873..803dcfb0e3469c6393a81e0ada1675ea56451eb7 100644 (file)
@@ -1771,7 +1771,7 @@ void x2apic_setup(void)
        __x2apic_enable();
 }
 
-static __init void apic_set_fixmap(void);
+static __init void apic_set_fixmap(bool read_apic);
 
 static __init void x2apic_disable(void)
 {
@@ -1793,7 +1793,12 @@ static __init void x2apic_disable(void)
        }
 
        __x2apic_disable();
-       apic_set_fixmap();
+       /*
+        * Don't reread the APIC ID as it was already done from
+        * check_x2apic() and the APIC driver still is a x2APIC variant,
+        * which fails to do the read after x2APIC was disabled.
+        */
+       apic_set_fixmap(false);
 }
 
 static __init void x2apic_enable(void)
@@ -2057,13 +2062,14 @@ void __init init_apic_mappings(void)
        }
 }
 
-static __init void apic_set_fixmap(void)
+static __init void apic_set_fixmap(bool read_apic)
 {
        set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
        apic_mmio_base = APIC_BASE;
        apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
                    apic_mmio_base, mp_lapic_addr);
-       apic_read_boot_cpu_id(false);
+       if (read_apic)
+               apic_read_boot_cpu_id(false);
 }
 
 void __init register_lapic_address(unsigned long address)
@@ -2073,7 +2079,7 @@ void __init register_lapic_address(unsigned long address)
        mp_lapic_addr = address;
 
        if (!x2apic_mode)
-               apic_set_fixmap();
+               apic_set_fixmap(true);
 }
 
 /*
index cb9eece55904d049edc600960bdaa0db58765459..307302af0aeee22d0f3871d06ee117bd6c82818d 100644 (file)
@@ -459,8 +459,7 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
 
        case 0x1a:
                switch (c->x86_model) {
-               case 0x00 ... 0x0f:
-               case 0x20 ... 0x2f:
+               case 0x00 ... 0x2f:
                case 0x40 ... 0x4f:
                case 0x70 ... 0x7f:
                        setup_force_cpu_cap(X86_FEATURE_ZEN5);
index a7aa6eff4ae5ba26206208479f7530721eebda2d..ce2d507c3b076652f9ec1cd39e1b86f1cda5fbc2 100644 (file)
@@ -119,7 +119,7 @@ static bool parse_8000_001e(struct topo_scan *tscan, bool has_0xb)
        return true;
 }
 
-static bool parse_fam10h_node_id(struct topo_scan *tscan)
+static void parse_fam10h_node_id(struct topo_scan *tscan)
 {
        union {
                struct {
@@ -131,20 +131,20 @@ static bool parse_fam10h_node_id(struct topo_scan *tscan)
        } nid;
 
        if (!boot_cpu_has(X86_FEATURE_NODEID_MSR))
-               return false;
+               return;
 
        rdmsrl(MSR_FAM10H_NODE_ID, nid.msr);
        store_node(tscan, nid.nodes_per_pkg + 1, nid.node_id);
        tscan->c->topo.llc_id = nid.node_id;
-       return true;
 }
 
 static void legacy_set_llc(struct topo_scan *tscan)
 {
        unsigned int apicid = tscan->c->topo.initial_apicid;
 
-       /* parse_8000_0008() set everything up except llc_id */
-       tscan->c->topo.llc_id = apicid >> tscan->dom_shifts[TOPO_CORE_DOMAIN];
+       /* If none of the parsers set LLC ID then use the die ID for it. */
+       if (tscan->c->topo.llc_id == BAD_APICID)
+               tscan->c->topo.llc_id = apicid >> tscan->dom_shifts[TOPO_CORE_DOMAIN];
 }
 
 static void topoext_fixup(struct topo_scan *tscan)
@@ -187,10 +187,7 @@ static void parse_topology_amd(struct topo_scan *tscan)
                return;
 
        /* Try the NODEID MSR */
-       if (parse_fam10h_node_id(tscan))
-               return;
-
-       legacy_set_llc(tscan);
+       parse_fam10h_node_id(tscan);
 }
 
 void cpu_parse_topology_amd(struct topo_scan *tscan)
@@ -198,6 +195,7 @@ void cpu_parse_topology_amd(struct topo_scan *tscan)
        tscan->amd_nodes_per_pkg = 1;
        topoext_fixup(tscan);
        parse_topology_amd(tscan);
+       legacy_set_llc(tscan);
 
        if (tscan->amd_nodes_per_pkg > 1)
                set_cpu_cap(tscan->c, X86_FEATURE_AMD_DCM);
index 6f1b379e3b3851bbef0b66945563076b8cde40c0..68b09f718f10e47b9efa59e017d7c1558be7f273 100644 (file)
@@ -532,9 +532,10 @@ u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type, enum
        return __e820__range_update(e820_table, start, size, old_type, new_type);
 }
 
-static u64 __init e820__range_update_kexec(u64 start, u64 size, enum e820_type old_type, enum e820_type  new_type)
+u64 __init e820__range_update_table(struct e820_table *t, u64 start, u64 size,
+                                   enum e820_type old_type, enum e820_type new_type)
 {
-       return __e820__range_update(e820_table_kexec, start, size, old_type, new_type);
+       return __e820__range_update(t, start, size, old_type, new_type);
 }
 
 /* Remove a range of memory from the E820 table: */
@@ -806,7 +807,7 @@ u64 __init e820__memblock_alloc_reserved(u64 size, u64 align)
 
        addr = memblock_phys_alloc(size, align);
        if (addr) {
-               e820__range_update_kexec(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
+               e820__range_update_table(e820_table_kexec, addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
                pr_info("update e820_table_kexec for e820__memblock_alloc_reserved()\n");
                e820__update_table_kexec();
        }
index 7062b84dd467d62ac1aed8c4fe4bdb86d5a7ac61..6d3d20e3e43a9b005f725d1e89dcc8fd81560dcd 100644 (file)
@@ -139,7 +139,7 @@ void __show_regs(struct pt_regs *regs, enum show_regs_mode mode,
                       log_lvl, d3, d6, d7);
        }
 
-       if (cpu_feature_enabled(X86_FEATURE_OSPKE))
+       if (cr4 & X86_CR4_PKE)
                printk("%sPKRU: %08x\n", log_lvl, read_pkru());
 }
 
index 8b04958da5e7d6c4bd096cffdaa4874e73433846..b4f8fa0f722cd6749079ba81d69458200c5051bb 100644 (file)
@@ -1203,12 +1203,14 @@ static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt,
                break;
 
        case SVM_EXIT_MONITOR:
-               if (opcode == 0x010f && modrm == 0xc8)
+               /* MONITOR and MONITORX instructions generate the same error code */
+               if (opcode == 0x010f && (modrm == 0xc8 || modrm == 0xfa))
                        return ES_OK;
                break;
 
        case SVM_EXIT_MWAIT:
-               if (opcode == 0x010f && modrm == 0xc9)
+               /* MWAIT and MWAITX instructions generate the same error code */
+               if (opcode == 0x010f && (modrm == 0xc9 || modrm == 0xfb))
                        return ES_OK;
                break;
 
index 622d12ec7f08518ba6701c33efd74d5f77545806..bba4e020dd646cc257056fa05ece3ccdc24ae560 100644 (file)
@@ -723,39 +723,8 @@ kernelmode_fixup_or_oops(struct pt_regs *regs, unsigned long error_code,
        WARN_ON_ONCE(user_mode(regs));
 
        /* Are we prepared to handle this kernel fault? */
-       if (fixup_exception(regs, X86_TRAP_PF, error_code, address)) {
-               /*
-                * Any interrupt that takes a fault gets the fixup. This makes
-                * the below recursive fault logic only apply to a faults from
-                * task context.
-                */
-               if (in_interrupt())
-                       return;
-
-               /*
-                * Per the above we're !in_interrupt(), aka. task context.
-                *
-                * In this case we need to make sure we're not recursively
-                * faulting through the emulate_vsyscall() logic.
-                */
-               if (current->thread.sig_on_uaccess_err && signal) {
-                       sanitize_error_code(address, &error_code);
-
-                       set_signal_archinfo(address, error_code);
-
-                       if (si_code == SEGV_PKUERR) {
-                               force_sig_pkuerr((void __user *)address, pkey);
-                       } else {
-                               /* XXX: hwpoison faults will set the wrong code. */
-                               force_sig_fault(signal, si_code, (void __user *)address);
-                       }
-               }
-
-               /*
-                * Barring that, we can do the fixup and be happy.
-                */
+       if (fixup_exception(regs, X86_TRAP_PF, error_code, address))
                return;
-       }
 
        /*
         * AMD erratum #91 manifests as a spurious page fault on a PREFETCH
index 6f3b3e028718556667c1d86e8f56442eafc78dcc..0a120d85d7bba88b33c59b97f9109a6acde727cd 100644 (file)
@@ -102,6 +102,13 @@ void __init mem_encrypt_setup_arch(void)
        phys_addr_t total_mem = memblock_phys_mem_size();
        unsigned long size;
 
+       /*
+        * Do RMP table fixups after the e820 tables have been setup by
+        * e820__memory_setup().
+        */
+       if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
+               snp_fixup_e820_tables();
+
        if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
                return;
 
index df5fac428408fe65ecc03766def03e0959bc539a..59cbc94b6e6903d915d9b16b04e82f269c88754b 100644 (file)
@@ -1807,36 +1807,41 @@ populate_extable:
                        if (BPF_MODE(insn->code) == BPF_PROBE_MEM ||
                            BPF_MODE(insn->code) == BPF_PROBE_MEMSX) {
                                /* Conservatively check that src_reg + insn->off is a kernel address:
-                                *   src_reg + insn->off >= TASK_SIZE_MAX + PAGE_SIZE
-                                * src_reg is used as scratch for src_reg += insn->off and restored
-                                * after emit_ldx if necessary
+                                *   src_reg + insn->off > TASK_SIZE_MAX + PAGE_SIZE
+                                *   and
+                                *   src_reg + insn->off < VSYSCALL_ADDR
                                 */
 
-                               u64 limit = TASK_SIZE_MAX + PAGE_SIZE;
+                               u64 limit = TASK_SIZE_MAX + PAGE_SIZE - VSYSCALL_ADDR;
                                u8 *end_of_jmp;
 
-                               /* At end of these emitted checks, insn->off will have been added
-                                * to src_reg, so no need to do relative load with insn->off offset
-                                */
-                               insn_off = 0;
+                               /* movabsq r10, VSYSCALL_ADDR */
+                               emit_mov_imm64(&prog, BPF_REG_AX, (long)VSYSCALL_ADDR >> 32,
+                                              (u32)(long)VSYSCALL_ADDR);
 
-                               /* movabsq r11, limit */
-                               EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG));
-                               EMIT((u32)limit, 4);
-                               EMIT(limit >> 32, 4);
+                               /* mov src_reg, r11 */
+                               EMIT_mov(AUX_REG, src_reg);
 
                                if (insn->off) {
-                                       /* add src_reg, insn->off */
-                                       maybe_emit_1mod(&prog, src_reg, true);
-                                       EMIT2_off32(0x81, add_1reg(0xC0, src_reg), insn->off);
+                                       /* add r11, insn->off */
+                                       maybe_emit_1mod(&prog, AUX_REG, true);
+                                       EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off);
                                }
 
-                               /* cmp src_reg, r11 */
-                               maybe_emit_mod(&prog, src_reg, AUX_REG, true);
-                               EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG));
+                               /* sub r11, r10 */
+                               maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true);
+                               EMIT2(0x29, add_2reg(0xC0, AUX_REG, BPF_REG_AX));
+
+                               /* movabsq r10, limit */
+                               emit_mov_imm64(&prog, BPF_REG_AX, (long)limit >> 32,
+                                              (u32)(long)limit);
+
+                               /* cmp r10, r11 */
+                               maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true);
+                               EMIT2(0x39, add_2reg(0xC0, AUX_REG, BPF_REG_AX));
 
-                               /* if unsigned '>=', goto load */
-                               EMIT2(X86_JAE, 0);
+                               /* if unsigned '>', goto load */
+                               EMIT2(X86_JA, 0);
                                end_of_jmp = prog;
 
                                /* xor dst_reg, dst_reg */
@@ -1862,18 +1867,6 @@ populate_extable:
                                /* populate jmp_offset for JMP above */
                                start_of_ldx[-1] = prog - start_of_ldx;
 
-                               if (insn->off && src_reg != dst_reg) {
-                                       /* sub src_reg, insn->off
-                                        * Restore src_reg after "add src_reg, insn->off" in prev
-                                        * if statement. But if src_reg == dst_reg, emit_ldx
-                                        * above already clobbered src_reg, so no need to restore.
-                                        * If add src_reg, insn->off was unnecessary, no need to
-                                        * restore either.
-                                        */
-                                       maybe_emit_1mod(&prog, src_reg, true);
-                                       EMIT2_off32(0x81, add_1reg(0xE8, src_reg), insn->off);
-                               }
-
                                if (!bpf_prog->aux->extable)
                                        break;
 
@@ -3473,3 +3466,9 @@ bool bpf_jit_supports_ptr_xchg(void)
 {
        return true;
 }
+
+/* x86-64 JIT emits its own code to filter user addresses so return 0 here */
+u64 bpf_arch_uaddress_limit(void)
+{
+       return 0;
+}
index ab0e8448bb6eb2bfbc4fab29321cd0ddbe876f7e..0ae10535c699982e15f20026a3e8012e52c41f32 100644 (file)
@@ -163,6 +163,42 @@ bool snp_probe_rmptable_info(void)
        return true;
 }
 
+static void __init __snp_fixup_e820_tables(u64 pa)
+{
+       if (IS_ALIGNED(pa, PMD_SIZE))
+               return;
+
+       /*
+        * Handle cases where the RMP table placement by the BIOS is not
+        * 2M aligned and the kexec kernel could try to allocate
+        * from within that chunk which then causes a fatal RMP fault.
+        *
+        * The e820_table needs to be updated as it is converted to
+        * kernel memory resources and used by KEXEC_FILE_LOAD syscall
+        * to load kexec segments.
+        *
+        * The e820_table_firmware needs to be updated as it is exposed
+        * to sysfs and used by the KEXEC_LOAD syscall to load kexec
+        * segments.
+        *
+        * The e820_table_kexec needs to be updated as it passed to
+        * the kexec-ed kernel.
+        */
+       pa = ALIGN_DOWN(pa, PMD_SIZE);
+       if (e820__mapped_any(pa, pa + PMD_SIZE, E820_TYPE_RAM)) {
+               pr_info("Reserving start/end of RMP table on a 2MB boundary [0x%016llx]\n", pa);
+               e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
+               e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
+               e820__range_update_table(e820_table_firmware, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED);
+       }
+}
+
+void __init snp_fixup_e820_tables(void)
+{
+       __snp_fixup_e820_tables(probed_rmp_base);
+       __snp_fixup_e820_tables(probed_rmp_base + probed_rmp_size);
+}
+
 /*
  * Do the necessary preparations which are verified by the firmware as
  * described in the SNP_INIT_EX firmware command description in the SNP
index ace2eb054053f95e53ac43992d9b778335e68748..9ba53814ed6a9e392b60c53477246977d649f20e 100644 (file)
@@ -219,13 +219,21 @@ static __read_mostly unsigned int cpuid_leaf5_edx_val;
 static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                      unsigned int *cx, unsigned int *dx)
 {
-       unsigned maskebx = ~0;
+       unsigned int maskebx = ~0;
+       unsigned int or_ebx = 0;
 
        /*
         * Mask out inconvenient features, to try and disable as many
         * unsupported kernel subsystems as possible.
         */
        switch (*ax) {
+       case 0x1:
+               /* Replace initial APIC ID in bits 24-31 of EBX. */
+               /* See xen_pv_smp_config() for related topology preparations. */
+               maskebx = 0x00ffffff;
+               or_ebx = smp_processor_id() << 24;
+               break;
+
        case CPUID_MWAIT_LEAF:
                /* Synthesize the values.. */
                *ax = 0;
@@ -248,6 +256,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                : "0" (*ax), "2" (*cx));
 
        *bx &= maskebx;
+       *bx |= or_ebx;
 }
 
 static bool __init xen_check_mwait(void)
index 27d1a5b7f571a3487cfa68a037e51516a6b9b287..ac41d83b38d3c49d3116dff58d5998a5fe9efb62 100644 (file)
@@ -154,9 +154,9 @@ static void __init xen_pv_smp_config(void)
        u32 apicid = 0;
        int i;
 
-       topology_register_boot_apic(apicid++);
+       topology_register_boot_apic(apicid);
 
-       for (i = 1; i < nr_cpu_ids; i++)
+       for (i = 0; i < nr_cpu_ids; i++)
                topology_register_apic(apicid++, CPU_ACPIID_INVALID, true);
 
        /* Pretend to be a proper enumerated system */
index 38bcecb0e457d9741c142cada4d38ec65ff0f88b..a2b6bb5429f5cb4c3c9694c9db6dbb8f6992d9fa 100644 (file)
@@ -100,6 +100,10 @@ void flush_cache_range(struct vm_area_struct*, ulong, ulong);
 void flush_icache_range(unsigned long start, unsigned long end);
 void flush_cache_page(struct vm_area_struct*,
                             unsigned long, unsigned long);
+#define flush_cache_all flush_cache_all
+#define flush_cache_range flush_cache_range
+#define flush_icache_range flush_icache_range
+#define flush_cache_page flush_cache_page
 #else
 #define flush_cache_all local_flush_cache_all
 #define flush_cache_range local_flush_cache_range
@@ -136,20 +140,7 @@ void local_flush_cache_page(struct vm_area_struct *vma,
 
 #else
 
-#define flush_cache_all()                              do { } while (0)
-#define flush_cache_mm(mm)                             do { } while (0)
-#define flush_cache_dup_mm(mm)                         do { } while (0)
-
-#define flush_cache_vmap(start,end)                    do { } while (0)
-#define flush_cache_vmap_early(start,end)              do { } while (0)
-#define flush_cache_vunmap(start,end)                  do { } while (0)
-
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)                                do { } while (0)
-
 #define flush_icache_range local_flush_icache_range
-#define flush_cache_page(vma, addr, pfn)               do { } while (0)
-#define flush_cache_range(vma, start, end)             do { } while (0)
 
 #endif
 
@@ -162,15 +153,14 @@ void local_flush_cache_page(struct vm_area_struct *vma,
                __invalidate_icache_range(start,(end) - (start));       \
        } while (0)
 
-#define flush_dcache_mmap_lock(mapping)                        do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)              do { } while (0)
-
 #if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
 
 extern void copy_to_user_page(struct vm_area_struct*, struct page*,
                unsigned long, void*, const void*, unsigned long);
 extern void copy_from_user_page(struct vm_area_struct*, struct page*,
                unsigned long, void*, const void*, unsigned long);
+#define copy_to_user_page copy_to_user_page
+#define copy_from_user_page copy_from_user_page
 
 #else
 
@@ -186,4 +176,6 @@ extern void copy_from_user_page(struct vm_area_struct*, struct page*,
 
 #endif
 
+#include <asm-generic/cacheflush.h>
+
 #endif /* _XTENSA_CACHEFLUSH_H */
index d008a153a2b9f7a9782b5874643f2d5a3741e995..7ed1a2085bd72883025c7de7d0d028ab077cc56c 100644 (file)
 #define MAKE_RA_FOR_CALL(ra,ws)   (((ra) & 0x3fffffff) | (ws) << 30)
 
 /* Convert return address to a valid pc
- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ * Note: 'text' is the address within the same 1GB range as the ra
  */
-#define MAKE_PC_FROM_RA(ra,sp)    (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
+#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000))
 
 #elif defined(__XTENSA_CALL0_ABI__)
 
 #define MAKE_RA_FOR_CALL(ra, ws)   (ra)
 
 /* Convert return address to a valid pc
- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ * Note: 'text' is not used as 'ra' is always the full address
  */
-#define MAKE_PC_FROM_RA(ra, sp)    (ra)
+#define MAKE_PC_FROM_RA(ra, text)  (ra)
 
 #else
 #error Unsupported Xtensa ABI
index a270467556dc84df2c6ceb0786acee3669a059f8..86c70117371bb7cc022b0793f0a4eb8ef834bc63 100644 (file)
@@ -87,7 +87,7 @@ struct pt_regs {
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
 # define instruction_pointer(regs) ((regs)->pc)
 # define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
-                                              (regs)->areg[1]))
+                                              (regs)->pc))
 
 # ifndef CONFIG_SMP
 #  define profile_pc(regs) instruction_pointer(regs)
index a815577d25fd02f3b267359d923cb83aae512c3d..7bd66677f7b6de58d0a1bda1b414ebc622dce962 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/regs.h>
 #include <asm/hw_breakpoint.h>
+#include <asm/sections.h>
 #include <asm/traps.h>
 
 extern void ret_from_fork(void);
@@ -380,7 +381,7 @@ unsigned long __get_wchan(struct task_struct *p)
        int count = 0;
 
        sp = p->thread.sp;
-       pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
+       pc = MAKE_PC_FROM_RA(p->thread.ra, _text);
 
        do {
                if (sp < stack_page + sizeof(struct task_struct) ||
@@ -392,7 +393,7 @@ unsigned long __get_wchan(struct task_struct *p)
 
                /* Stack layout: sp-4: ra, sp-3: sp' */
 
-               pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp);
+               pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text);
                sp = SPILL_SLOT(sp, 1);
        } while (count++ < 16);
        return 0;
index 831ffb648bda7e160408fd97530eddee760c27fc..ed324fdf2a2f9124527a5514ce14ac731996a2ad 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/stacktrace.h>
 
 #include <asm/ftrace.h>
+#include <asm/sections.h>
 #include <asm/stacktrace.h>
 #include <asm/traps.h>
 #include <linux/uaccess.h>
@@ -189,7 +190,7 @@ void walk_stackframe(unsigned long *sp,
                if (a1 <= (unsigned long)sp)
                        break;
 
-               frame.pc = MAKE_PC_FROM_RA(a0, a1);
+               frame.pc = MAKE_PC_FROM_RA(a0, _text);
                frame.sp = a1;
 
                if (fn(&frame, data))
index 8896e691c051eab87ba88ffcbac01bd4860df0de..abec44b687dff0d4da3a77307603a0866a35ce88 100644 (file)
@@ -166,10 +166,8 @@ late_initcall(rs_init);
 
 static void iss_console_write(struct console *co, const char *s, unsigned count)
 {
-       if (s && *s != 0) {
-               int len = strlen(s);
-               simc_write(1, s, count < len ? count : len);
-       }
+       if (s && *s != 0)
+               simc_write(1, s, min(count, strlen(s)));
 }
 
 static struct tty_driver* iss_console_device(struct console *c, int *index)
index da2a167a4d08b66fe26c99826a9e84277f76f0e3..2af3dca56f3db67692b3ab4d63b5cb6544e2a819 100644 (file)
@@ -912,7 +912,7 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
                disk_unblock_events(disk);
 
        bdev_file->f_flags |= O_LARGEFILE;
-       bdev_file->f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT;
+       bdev_file->f_mode |= FMODE_CAN_ODIRECT;
        if (bdev_nowait(bdev))
                bdev_file->f_mode |= FMODE_NOWAIT;
        if (mode & BLK_OPEN_RESTRICT_WRITES)
index d2731843f2fccb481eda94e1a1dc980051d2486a..9d6033e01f2e170307cbe5ffdb0365d1eb5c8b9b 100644 (file)
@@ -188,7 +188,10 @@ static int blk_validate_limits(struct queue_limits *lim)
         * bvec and lower layer bio splitting is supposed to handle the two
         * correctly.
         */
-       if (!lim->virt_boundary_mask) {
+       if (lim->virt_boundary_mask) {
+               if (!lim->max_segment_size)
+                       lim->max_segment_size = UINT_MAX;
+       } else {
                /*
                 * The maximum segment size has an odd historic 64k default that
                 * drivers probably should override.  Just like the I/O size we
index 679d9b752fe828eb64b67d17e7492469c71e35d3..af6c244314afadb0674c1c354bf749de0f1ef74f 100644 (file)
@@ -863,6 +863,7 @@ const struct file_operations def_blk_fops = {
        .splice_read    = filemap_splice_read,
        .splice_write   = iter_file_splice_write,
        .fallocate      = blkdev_fallocate,
+       .fop_flags      = FOP_BUFFER_RASYNC,
 };
 
 static __init int blkdev_init(void)
index 151d95f96b116c477889b016243ad23c338e709f..69d2138d7efb59d49ddd8414581615f2378fc914 100644 (file)
@@ -16,6 +16,9 @@ menuconfig AUXDISPLAY
 
 if AUXDISPLAY
 
+#
+# Character LCD section
+#
 config CHARLCD
        tristate "Character LCD core support" if COMPILE_TEST
        help
@@ -25,12 +28,6 @@ config CHARLCD
          This is some character LCD core interface that multiple drivers can
          use.
 
-config LINEDISP
-       tristate "Character line display core support" if COMPILE_TEST
-       help
-         This is the core support for single-line character displays, to be
-         selected by drivers that use it.
-
 config HD44780_COMMON
        tristate "Common functions for HD44780 (and compatibles) LCD displays" if COMPILE_TEST
        select CHARLCD
@@ -52,145 +49,6 @@ config HD44780
          kernel and started at boot.
          If you don't understand what all this is about, say N.
 
-config KS0108
-       tristate "KS0108 LCD Controller"
-       depends on PARPORT_PC
-       default n
-       help
-         If you have a LCD controlled by one or more KS0108
-         controllers, say Y. You will need also another more specific
-         driver for your LCD.
-
-         Depends on Parallel Port support. If you say Y at
-         parport, you will be able to compile this as a module (M)
-         and built-in as well (Y).
-
-         To compile this as a module, choose M here:
-         the module will be called ks0108.
-
-         If unsure, say N.
-
-config KS0108_PORT
-       hex "Parallel port where the LCD is connected"
-       depends on KS0108
-       default 0x378
-       help
-         The address of the parallel port where the LCD is connected.
-
-         The first  standard parallel port address is 0x378.
-         The second standard parallel port address is 0x278.
-         The third  standard parallel port address is 0x3BC.
-
-         You can specify a different address if you need.
-
-         If you don't know what I'm talking about, load the parport module,
-         and execute "dmesg" or "cat /proc/ioports". You can see there how
-         many parallel ports are present and which address each one has.
-
-         Usually you only need to use 0x378.
-
-         If you compile this as a module, you can still override this
-         using the module parameters.
-
-config KS0108_DELAY
-       int "Delay between each control writing (microseconds)"
-       depends on KS0108
-       default "2"
-       help
-         Amount of time the ks0108 should wait between each control write
-         to the parallel port.
-
-         If your LCD seems to miss random writings, increment this.
-
-         If you don't know what I'm talking about, ignore it.
-
-         If you compile this as a module, you can still override this
-         value using the module parameters.
-
-config CFAG12864B
-       tristate "CFAG12864B LCD"
-       depends on X86
-       depends on FB
-       depends on KS0108
-       select FB_SYSMEM_HELPERS
-       default n
-       help
-         If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
-         say Y. You also need the ks0108 LCD Controller driver.
-
-         For help about how to wire your LCD to the parallel port,
-         check Documentation/admin-guide/auxdisplay/cfag12864b.rst
-
-         Depends on the x86 arch and the framebuffer support.
-
-         The LCD framebuffer driver can be attached to a console.
-         It will work fine. However, you can't attach it to the fbdev driver
-         of the xorg server.
-
-         To compile this as a module, choose M here:
-         the modules will be called cfag12864b and cfag12864bfb.
-
-         If unsure, say N.
-
-config CFAG12864B_RATE
-       int "Refresh rate (hertz)"
-       depends on CFAG12864B
-       default "20"
-       help
-         Refresh rate of the LCD.
-
-         As the LCD is not memory mapped, the driver has to make the work by
-         software. This means you should be careful setting this value higher.
-         If your CPUs are really slow or you feel the system is slowed down,
-         decrease the value.
-
-         Be careful modifying this value to a very high value:
-         You can freeze the computer, or the LCD maybe can't draw as fast as you
-         are requesting.
-
-         If you don't know what I'm talking about, ignore it.
-
-         If you compile this as a module, you can still override this
-         value using the module parameters.
-
-config IMG_ASCII_LCD
-       tristate "Imagination Technologies ASCII LCD Display"
-       depends on HAS_IOMEM
-       default y if MIPS_MALTA
-       select MFD_SYSCON
-       select LINEDISP
-       help
-         Enable this to support the simple ASCII LCD displays found on
-         development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3
-         from Imagination Technologies.
-
-config HT16K33
-       tristate "Holtek Ht16K33 LED controller with keyscan"
-       depends on FB && I2C && INPUT
-       select FB_SYSMEM_HELPERS
-       select INPUT_MATRIXKMAP
-       select FB_BACKLIGHT
-       select NEW_LEDS
-       select LEDS_CLASS
-       select LINEDISP
-       help
-         Say yes here to add support for Holtek HT16K33, RAM mapping 16*8
-         LED controller driver with keyscan.
-
-config MAX6959
-       tristate "Maxim MAX6958/6959 7-segment LED controller"
-       depends on I2C
-       select REGMAP_I2C
-       select LINEDISP
-       help
-         If you say yes here you get support for the following Maxim chips
-         (I2C 7-segment LED display controller):
-         - MAX6958
-         - MAX6959 (input support)
-
-         This driver can also be built as a module. If so, the module
-         will be called max6959.
-
 config LCD2S
        tristate "lcd2s 20x4 character display over I2C console"
        depends on I2C
@@ -201,27 +59,6 @@ config LCD2S
          is a simple single color character display. You have to connect it
          to an I2C bus.
 
-config ARM_CHARLCD
-       bool "ARM Ltd. Character LCD Driver"
-       depends on PLAT_VERSATILE
-       help
-         This is a driver for the character LCD found on the ARM Ltd.
-         Versatile and RealView Platform Baseboards. It doesn't do
-         very much more than display the text "ARM Linux" on the first
-         line and the Linux version on the second line, but that's
-         still useful.
-
-config SEG_LED_GPIO
-       tristate "Generic 7-segment LED display"
-       depends on GPIOLIB || COMPILE_TEST
-       select LINEDISP
-       help
-         This driver supports a generic 7-segment LED display made up
-         of GPIO pins connected to the individual segments.
-
-         This driver can also be built as a module. If so, the module
-         will be called seg-led-gpio.
-
 menuconfig PARPORT_PANEL
        tristate "Parallel port LCD/Keypad Panel support"
        depends on PARPORT
@@ -480,7 +317,6 @@ endif # PARPORT_PANEL
 config PANEL_CHANGE_MESSAGE
        bool "Change LCD initialization message ?"
        depends on CHARLCD
-       default "n"
        help
          This allows you to replace the boot message indicating the kernel version
          and the driver version with a custom message. This is useful on appliances
@@ -529,8 +365,184 @@ choice
 
 endchoice
 
+#
+# Samsung KS0108 LCD controller section
+#
+config KS0108
+       tristate "KS0108 LCD Controller"
+       depends on PARPORT_PC
+       help
+         If you have a LCD controlled by one or more KS0108
+         controllers, say Y. You will need also another more specific
+         driver for your LCD.
+
+         Depends on Parallel Port support. If you say Y at
+         parport, you will be able to compile this as a module (M)
+         and built-in as well (Y).
+
+         To compile this as a module, choose M here:
+         the module will be called ks0108.
+
+         If unsure, say N.
+
+config KS0108_PORT
+       hex "Parallel port where the LCD is connected"
+       depends on KS0108
+       default 0x378
+       help
+         The address of the parallel port where the LCD is connected.
+
+         The first  standard parallel port address is 0x378.
+         The second standard parallel port address is 0x278.
+         The third  standard parallel port address is 0x3BC.
+
+         You can specify a different address if you need.
+
+         If you don't know what I'm talking about, load the parport module,
+         and execute "dmesg" or "cat /proc/ioports". You can see there how
+         many parallel ports are present and which address each one has.
+
+         Usually you only need to use 0x378.
+
+         If you compile this as a module, you can still override this
+         using the module parameters.
+
+config KS0108_DELAY
+       int "Delay between each control writing (microseconds)"
+       depends on KS0108
+       default "2"
+       help
+         Amount of time the ks0108 should wait between each control write
+         to the parallel port.
+
+         If your LCD seems to miss random writings, increment this.
+
+         If you don't know what I'm talking about, ignore it.
+
+         If you compile this as a module, you can still override this
+         value using the module parameters.
+
+config CFAG12864B
+       tristate "CFAG12864B LCD"
+       depends on X86
+       depends on FB
+       depends on KS0108
+       select FB_SYSMEM_HELPERS
+       help
+         If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
+         say Y. You also need the ks0108 LCD Controller driver.
+
+         For help about how to wire your LCD to the parallel port,
+         check Documentation/admin-guide/auxdisplay/cfag12864b.rst
+
+         Depends on the x86 arch and the framebuffer support.
+
+         The LCD framebuffer driver can be attached to a console.
+         It will work fine. However, you can't attach it to the fbdev driver
+         of the xorg server.
+
+         To compile this as a module, choose M here:
+         the modules will be called cfag12864b and cfag12864bfb.
+
+         If unsure, say N.
+
+config CFAG12864B_RATE
+       int "Refresh rate (hertz)"
+       depends on CFAG12864B
+       default "20"
+       help
+         Refresh rate of the LCD.
+
+         As the LCD is not memory mapped, the driver has to make the work by
+         software. This means you should be careful setting this value higher.
+         If your CPUs are really slow or you feel the system is slowed down,
+         decrease the value.
+
+         Be careful modifying this value to a very high value:
+         You can freeze the computer, or the LCD maybe can't draw as fast as you
+         are requesting.
+
+         If you don't know what I'm talking about, ignore it.
+
+         If you compile this as a module, you can still override this
+         value using the module parameters.
+
+#
+# Single character line display section
+#
+config LINEDISP
+       tristate "Character line display core support" if COMPILE_TEST
+       help
+         This is the core support for single-line character displays, to be
+         selected by drivers that use it.
+
+config IMG_ASCII_LCD
+       tristate "Imagination Technologies ASCII LCD Display"
+       depends on HAS_IOMEM
+       default y if MIPS_MALTA
+       select MFD_SYSCON
+       select LINEDISP
+       help
+         Enable this to support the simple ASCII LCD displays found on
+         development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3
+         from Imagination Technologies.
+
+config HT16K33
+       tristate "Holtek Ht16K33 LED controller with keyscan"
+       depends on FB && I2C && INPUT
+       select FB_SYSMEM_HELPERS
+       select INPUT_MATRIXKMAP
+       select FB_BACKLIGHT
+       select NEW_LEDS
+       select LEDS_CLASS
+       select LINEDISP
+       help
+         Say yes here to add support for Holtek HT16K33, RAM mapping 16*8
+         LED controller driver with keyscan.
+
+config MAX6959
+       tristate "Maxim MAX6958/6959 7-segment LED controller"
+       depends on I2C
+       select REGMAP_I2C
+       select LINEDISP
+       help
+         If you say yes here you get support for the following Maxim chips
+         (I2C 7-segment LED display controller):
+         - MAX6958
+         - MAX6959 (input support)
+
+         This driver can also be built as a module. If so, the module
+         will be called max6959.
+
+config SEG_LED_GPIO
+       tristate "Generic 7-segment LED display"
+       depends on GPIOLIB || COMPILE_TEST
+       select LINEDISP
+       help
+         This driver supports a generic 7-segment LED display made up
+         of GPIO pins connected to the individual segments.
+
+         This driver can also be built as a module. If so, the module
+         will be called seg-led-gpio.
+
+#
+# Character LCD with non-conforming interface section
+#
+config ARM_CHARLCD
+       bool "ARM Ltd. Character LCD Driver"
+       depends on PLAT_VERSATILE
+       help
+         This is a driver for the character LCD found on the ARM Ltd.
+         Versatile and RealView Platform Baseboards. It doesn't do
+         very much more than display the text "ARM Linux" on the first
+         line and the Linux version on the second line, but that's
+         still useful.
+
 endif # AUXDISPLAY
 
+#
+# Deprecated options
+#
 config PANEL
        tristate "Parallel port LCD/Keypad Panel support (OLD OPTION)"
        depends on PARPORT
index 4a8ea41b0550151e5312f0567034337286ef4019..f5c13ed1cd4f57311417fc0f5001d3fac16ec29e 100644 (file)
@@ -3,16 +3,16 @@
 # Makefile for the kernel auxiliary displays device drivers.
 #
 
-obj-$(CONFIG_CHARLCD)          += charlcd.o
-obj-$(CONFIG_HD44780_COMMON)   += hd44780_common.o
 obj-$(CONFIG_ARM_CHARLCD)      += arm-charlcd.o
-obj-$(CONFIG_KS0108)           += ks0108.o
 obj-$(CONFIG_CFAG12864B)       += cfag12864b.o cfag12864bfb.o
-obj-$(CONFIG_IMG_ASCII_LCD)    += img-ascii-lcd.o
+obj-$(CONFIG_CHARLCD)          += charlcd.o
+obj-$(CONFIG_HD44780_COMMON)   += hd44780_common.o
 obj-$(CONFIG_HD44780)          += hd44780.o
 obj-$(CONFIG_HT16K33)          += ht16k33.o
-obj-$(CONFIG_PARPORT_PANEL)    += panel.o
+obj-$(CONFIG_IMG_ASCII_LCD)    += img-ascii-lcd.o
+obj-$(CONFIG_KS0108)           += ks0108.o
 obj-$(CONFIG_LCD2S)            += lcd2s.o
 obj-$(CONFIG_LINEDISP)         += line-display.o
 obj-$(CONFIG_MAX6959)          += max6959.o
+obj-$(CONFIG_PARPORT_PANEL)    += panel.o
 obj-$(CONFIG_SEG_LED_GPIO)     += seg-led-gpio.o
index 6d309e4971b617ded2c7eecc26fbe3a88ed2a015..bb94638144546ea5710f247bab0601522b4b8796 100644 (file)
@@ -17,7 +17,9 @@
 #include <linux/uaccess.h>
 #include <linux/workqueue.h>
 
+#ifndef CONFIG_PANEL_BOOT_MESSAGE
 #include <generated/utsrelease.h>
+#endif
 
 #include "charlcd.h"
 
@@ -678,4 +680,5 @@ int charlcd_unregister(struct charlcd *lcd)
 }
 EXPORT_SYMBOL_GPL(charlcd_unregister);
 
+MODULE_DESCRIPTION("Character LCD core support");
 MODULE_LICENSE("GPL");
index 35a8dbb1e9d2762af6e11a3ae202af07c3aced18..183ab3011cbb1904e1c5ae40705a33b73ff859f3 100644 (file)
@@ -81,14 +81,12 @@ static int seg_led_probe(struct platform_device *pdev)
        return linedisp_register(&priv->linedisp, dev, 1, &seg_led_linedisp_ops);
 }
 
-static int seg_led_remove(struct platform_device *pdev)
+static void seg_led_remove(struct platform_device *pdev)
 {
        struct seg_led_priv *priv = platform_get_drvdata(pdev);
 
        cancel_delayed_work_sync(&priv->work);
        linedisp_unregister(&priv->linedisp);
-
-       return 0;
 }
 
 static const struct of_device_id seg_led_of_match[] = {
@@ -99,7 +97,7 @@ MODULE_DEVICE_TABLE(of, seg_led_of_match);
 
 static struct platform_driver seg_led_driver = {
        .probe = seg_led_probe,
-       .remove = seg_led_remove,
+       .remove_new = seg_led_remove,
        .driver = {
                .name = "seg-led-gpio",
                .of_match_table = seg_led_of_match,
index 5cb425f6f02d4bd1e4aa4f0e58d846a52896fdca..0a34dd3c4f38d298b8766065026cc465801f7aa7 100644 (file)
@@ -2838,6 +2838,43 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
 }
 EXPORT_SYMBOL_GPL(regmap_read);
 
+/**
+ * regmap_read_bypassed() - Read a value from a single register direct
+ *                         from the device, bypassing the cache
+ *
+ * @map: Register map to read from
+ * @reg: Register to be read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val)
+{
+       int ret;
+       bool bypass, cache_only;
+
+       if (!IS_ALIGNED(reg, map->reg_stride))
+               return -EINVAL;
+
+       map->lock(map->lock_arg);
+
+       bypass = map->cache_bypass;
+       cache_only = map->cache_only;
+       map->cache_bypass = true;
+       map->cache_only = false;
+
+       ret = _regmap_read(map, reg, val);
+
+       map->cache_bypass = bypass;
+       map->cache_only = cache_only;
+
+       map->unlock(map->lock_arg);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_read_bypassed);
+
 /**
  * regmap_raw_read() - Read raw data from the device
  *
index bea3d5cf8a83487909270d5f2398267250507a31..374e4efa8759fba62df2cdbbc49c9428ddb5ea5b 100644 (file)
@@ -2177,7 +2177,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
                .max_hw_sectors         = p->max_sectors,
                .chunk_sectors          = p->chunk_sectors,
                .virt_boundary_mask     = p->virt_boundary_mask,
-
+               .max_segments           = USHRT_MAX,
+               .max_segment_size       = UINT_MAX,
        };
        struct gendisk *disk;
        int ret = -EINVAL;
index 216826c31ee34f0e65ef74edcab98c7cd9eff7e5..638074992c829b71b5f6682a39b850c77757757a 100644 (file)
@@ -15,8 +15,6 @@
 
 #define VERSION "0.1"
 
-#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }})
-
 int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
                         enum qca_btsoc_type soc_type)
 {
@@ -101,7 +99,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
 {
        struct sk_buff *skb;
        struct edl_event_hdr *edl;
-       char cmd, build_label[QCA_FW_BUILD_VER_LEN];
+       char *build_label;
+       char cmd;
        int build_lbl_len, err = 0;
 
        bt_dev_dbg(hdev, "QCA read fw build info");
@@ -116,6 +115,11 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
                return err;
        }
 
+       if (skb->len < sizeof(*edl)) {
+               err = -EILSEQ;
+               goto out;
+       }
+
        edl = (struct edl_event_hdr *)(skb->data);
        if (!edl) {
                bt_dev_err(hdev, "QCA read fw build info with no header");
@@ -131,14 +135,25 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
                goto out;
        }
 
+       if (skb->len < sizeof(*edl) + 1) {
+               err = -EILSEQ;
+               goto out;
+       }
+
        build_lbl_len = edl->data[0];
-       if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) {
-               memcpy(build_label, edl->data + 1, build_lbl_len);
-               *(build_label + build_lbl_len) = '\0';
+
+       if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {
+               err = -EILSEQ;
+               goto out;
        }
 
+       build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);
+       if (!build_label)
+               goto out;
+
        hci_set_fw_info(hdev, "%s", build_label);
 
+       kfree(build_label);
 out:
        kfree_skb(skb);
        return err;
@@ -237,6 +252,11 @@ static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)
                goto out;
        }
 
+       if (skb->len < 3) {
+               err = -EILSEQ;
+               goto out;
+       }
+
        *bid = (edl->data[1] << 8) + edl->data[2];
        bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
 
@@ -267,9 +287,10 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
 
-static void qca_tlv_check_data(struct hci_dev *hdev,
+static int qca_tlv_check_data(struct hci_dev *hdev,
                               struct qca_fw_config *config,
-               u8 *fw_data, enum qca_btsoc_type soc_type)
+                              u8 *fw_data, size_t fw_size,
+                              enum qca_btsoc_type soc_type)
 {
        const u8 *data;
        u32 type_len;
@@ -279,12 +300,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
        struct tlv_type_patch *tlv_patch;
        struct tlv_type_nvm *tlv_nvm;
        uint8_t nvm_baud_rate = config->user_baud_rate;
+       u8 type;
 
        config->dnld_mode = QCA_SKIP_EVT_NONE;
        config->dnld_type = QCA_SKIP_EVT_NONE;
 
        switch (config->type) {
        case ELF_TYPE_PATCH:
+               if (fw_size < 7)
+                       return -EINVAL;
+
                config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
                config->dnld_type = QCA_SKIP_EVT_VSE_CC;
 
@@ -293,6 +318,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
                bt_dev_dbg(hdev, "File version      : 0x%x", fw_data[6]);
                break;
        case TLV_TYPE_PATCH:
+               if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))
+                       return -EINVAL;
+
                tlv = (struct tlv_type_hdr *)fw_data;
                type_len = le32_to_cpu(tlv->type_len);
                tlv_patch = (struct tlv_type_patch *)tlv->data;
@@ -332,25 +360,64 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
                break;
 
        case TLV_TYPE_NVM:
+               if (fw_size < sizeof(struct tlv_type_hdr))
+                       return -EINVAL;
+
                tlv = (struct tlv_type_hdr *)fw_data;
 
                type_len = le32_to_cpu(tlv->type_len);
-               length = (type_len >> 8) & 0x00ffffff;
+               length = type_len >> 8;
+               type = type_len & 0xff;
 
-               BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
+               /* Some NVM files have more than one set of tags, only parse
+                * the first set when it has type 2 for now. When there is
+                * more than one set there is an enclosing header of type 4.
+                */
+               if (type == 4) {
+                       if (fw_size < 2 * sizeof(struct tlv_type_hdr))
+                               return -EINVAL;
+
+                       tlv++;
+
+                       type_len = le32_to_cpu(tlv->type_len);
+                       length = type_len >> 8;
+                       type = type_len & 0xff;
+               }
+
+               BT_DBG("TLV Type\t\t : 0x%x", type);
                BT_DBG("Length\t\t : %d bytes", length);
 
+               if (type != 2)
+                       break;
+
+               if (fw_size < length + (tlv->data - fw_data))
+                       return -EINVAL;
+
                idx = 0;
                data = tlv->data;
-               while (idx < length) {
+               while (idx < length - sizeof(struct tlv_type_nvm)) {
                        tlv_nvm = (struct tlv_type_nvm *)(data + idx);
 
                        tag_id = le16_to_cpu(tlv_nvm->tag_id);
                        tag_len = le16_to_cpu(tlv_nvm->tag_len);
 
+                       if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)
+                               return -EINVAL;
+
                        /* Update NVM tags as needed */
                        switch (tag_id) {
+                       case EDL_TAG_ID_BD_ADDR:
+                               if (tag_len != sizeof(bdaddr_t))
+                                       return -EINVAL;
+
+                               memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t));
+
+                               break;
+
                        case EDL_TAG_ID_HCI:
+                               if (tag_len < 3)
+                                       return -EINVAL;
+
                                /* HCI transport layer parameters
                                 * enabling software inband sleep
                                 * onto controller side.
@@ -366,6 +433,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
                                break;
 
                        case EDL_TAG_ID_DEEP_SLEEP:
+                               if (tag_len < 1)
+                                       return -EINVAL;
+
                                /* Sleep enable mask
                                 * enabling deep sleep feature on controller.
                                 */
@@ -374,14 +444,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
                                break;
                        }
 
-                       idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
+                       idx += sizeof(struct tlv_type_nvm) + tag_len;
                }
                break;
 
        default:
                BT_ERR("Unknown TLV type %d", config->type);
-               break;
+               return -EINVAL;
        }
+
+       return 0;
 }
 
 static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
@@ -531,7 +603,9 @@ static int qca_download_firmware(struct hci_dev *hdev,
        memcpy(data, fw->data, size);
        release_firmware(fw);
 
-       qca_tlv_check_data(hdev, config, data, soc_type);
+       ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
+       if (ret)
+               goto out;
 
        segment = data;
        remain = size;
@@ -614,7 +688,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 }
 EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
 
-static int qca_check_bdaddr(struct hci_dev *hdev)
+static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
 {
        struct hci_rp_read_bd_addr *bda;
        struct sk_buff *skb;
@@ -638,7 +712,7 @@ static int qca_check_bdaddr(struct hci_dev *hdev)
        }
 
        bda = (struct hci_rp_read_bd_addr *)skb->data;
-       if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT))
+       if (!bacmp(&bda->bdaddr, &config->bdaddr))
                set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
 
        kfree_skb(skb);
@@ -667,7 +741,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
                   enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
                   const char *firmware_name)
 {
-       struct qca_fw_config config;
+       struct qca_fw_config config = {};
        int err;
        u8 rom_ver = 0;
        u32 soc_ver;
@@ -852,7 +926,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
                break;
        }
 
-       err = qca_check_bdaddr(hdev);
+       err = qca_check_bdaddr(hdev, &config);
        if (err)
                return err;
 
index dc31984f71dc132e7ebf0502e9886b60f8d17fb3..215433fd76a106a21c8c70538e491eb79cb77879 100644 (file)
@@ -29,6 +29,7 @@
 #define EDL_PATCH_CONFIG_RES_EVT       (0x00)
 #define QCA_DISABLE_LOGGING_SUB_OP     (0x14)
 
+#define EDL_TAG_ID_BD_ADDR             2
 #define EDL_TAG_ID_HCI                 (17)
 #define EDL_TAG_ID_DEEP_SLEEP          (27)
 
@@ -47,7 +48,6 @@
 #define get_soc_ver(soc_id, rom_ver)   \
        ((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
 
-#define QCA_FW_BUILD_VER_LEN           255
 #define QCA_HSP_GF_SOC_ID                      0x1200
 #define QCA_HSP_GF_SOC_MASK                    0x0000ff00
 
@@ -94,6 +94,7 @@ struct qca_fw_config {
        uint8_t user_baud_rate;
        enum qca_tlv_dnld_mode dnld_mode;
        enum qca_tlv_dnld_mode dnld_type;
+       bdaddr_t bdaddr;
 };
 
 struct edl_event_hdr {
index d5e7fa9173a1690656494e09333cdf98099ba7c7..64cd2ee03aa3a4f48f0aec8ff87dee1b95fedb8c 100644 (file)
@@ -163,6 +163,16 @@ config QCOM_SSC_BLOCK_BUS
          i2c/spi/uart controllers, a hexagon core, and a clock controller
          which provides clocks for the above.
 
+config STM32_FIREWALL
+       bool "STM32 Firewall framework"
+       depends on (ARCH_STM32 || COMPILE_TEST) && OF
+       select OF_DYNAMIC
+       help
+         Say y to enable STM32 firewall framework and its services. Firewall
+         controllers will be able to register to the framework. Access for
+         hardware resources linked to a firewall controller can be requested
+         through this STM32 framework.
+
 config SUN50I_DE2_BUS
        bool "Allwinner A64 DE2 Bus Driver"
          default ARM64
index d90eed189a65b0e7ddb7731e125f641d692a6e6d..cddd4984d6afe118b4d32477de2f39d87ccd6107 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_OMAP_INTERCONNECT)       += omap_l3_smx.o omap_l3_noc.o
 obj-$(CONFIG_OMAP_OCP2SCP)     += omap-ocp2scp.o
 obj-$(CONFIG_QCOM_EBI2)                += qcom-ebi2.o
 obj-$(CONFIG_QCOM_SSC_BLOCK_BUS)       += qcom-ssc-block-bus.o
+obj-$(CONFIG_STM32_FIREWALL)   += stm32_firewall.o stm32_rifsc.o stm32_etzpc.o
 obj-$(CONFIG_SUN50I_DE2_BUS)   += sun50i-de2.o
 obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
 obj-$(CONFIG_OF)               += simple-pm-bus.o
index 65ae758f3194366bd614df7a3acc485f6d5697ce..ee29162da4ee8f430164bc80d3975bf09fbdc254 100644 (file)
@@ -410,6 +410,7 @@ static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
        { .compatible = "brcm,bcm74165-gisb-arb", .data = gisb_offsets_bcm74165 },
        { },
 };
+MODULE_DEVICE_TABLE(of, brcmstb_gisb_arb_of_match);
 
 static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
 {
diff --git a/drivers/bus/stm32_etzpc.c b/drivers/bus/stm32_etzpc.c
new file mode 100644 (file)
index 0000000..7fc0f16
--- /dev/null
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "stm32_firewall.h"
+
+/*
+ * ETZPC registers
+ */
+#define ETZPC_DECPROT                  0x10
+#define ETZPC_HWCFGR                   0x3F0
+
+/*
+ * HWCFGR register
+ */
+#define ETZPC_HWCFGR_NUM_TZMA          GENMASK(7, 0)
+#define ETZPC_HWCFGR_NUM_PER_SEC       GENMASK(15, 8)
+#define ETZPC_HWCFGR_NUM_AHB_SEC       GENMASK(23, 16)
+#define ETZPC_HWCFGR_CHUNKS1N4         GENMASK(31, 24)
+
+/*
+ * ETZPC miscellaneous
+ */
+#define ETZPC_PROT_MASK                        GENMASK(1, 0)
+#define ETZPC_PROT_A7NS                        0x3
+#define ETZPC_DECPROT_SHIFT            1
+
+#define IDS_PER_DECPROT_REGS           16
+
+static int stm32_etzpc_grant_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
+{
+       u32 offset, reg_offset, sec_val;
+
+       if (firewall_id >= ctrl->max_entries) {
+               dev_err(ctrl->dev, "Invalid sys bus ID %u", firewall_id);
+               return -EINVAL;
+       }
+
+       /* Check access configuration, 16 peripherals per register */
+       reg_offset = ETZPC_DECPROT + 0x4 * (firewall_id / IDS_PER_DECPROT_REGS);
+       offset = (firewall_id % IDS_PER_DECPROT_REGS) << ETZPC_DECPROT_SHIFT;
+
+       /* Verify peripheral is non-secure and attributed to cortex A7 */
+       sec_val = (readl(ctrl->mmio + reg_offset) >> offset) & ETZPC_PROT_MASK;
+       if (sec_val != ETZPC_PROT_A7NS) {
+               dev_dbg(ctrl->dev, "Invalid bus configuration: reg_offset %#x, value %d\n",
+                       reg_offset, sec_val);
+               return -EACCES;
+       }
+
+       return 0;
+}
+
+static void stm32_etzpc_release_access(struct stm32_firewall_controller *ctrl __maybe_unused,
+                                      u32 firewall_id __maybe_unused)
+{
+}
+
+static int stm32_etzpc_probe(struct platform_device *pdev)
+{
+       struct stm32_firewall_controller *etzpc_controller;
+       struct device_node *np = pdev->dev.of_node;
+       u32 nb_per, nb_master;
+       struct resource *res;
+       void __iomem *mmio;
+       int rc;
+
+       etzpc_controller = devm_kzalloc(&pdev->dev, sizeof(*etzpc_controller), GFP_KERNEL);
+       if (!etzpc_controller)
+               return -ENOMEM;
+
+       mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(mmio))
+               return PTR_ERR(mmio);
+
+       etzpc_controller->dev = &pdev->dev;
+       etzpc_controller->mmio = mmio;
+       etzpc_controller->name = dev_driver_string(etzpc_controller->dev);
+       etzpc_controller->type = STM32_PERIPHERAL_FIREWALL | STM32_MEMORY_FIREWALL;
+       etzpc_controller->grant_access = stm32_etzpc_grant_access;
+       etzpc_controller->release_access = stm32_etzpc_release_access;
+
+       /* Get number of etzpc entries*/
+       nb_per = FIELD_GET(ETZPC_HWCFGR_NUM_PER_SEC,
+                          readl(etzpc_controller->mmio + ETZPC_HWCFGR));
+       nb_master = FIELD_GET(ETZPC_HWCFGR_NUM_AHB_SEC,
+                             readl(etzpc_controller->mmio + ETZPC_HWCFGR));
+       etzpc_controller->max_entries = nb_per + nb_master;
+
+       platform_set_drvdata(pdev, etzpc_controller);
+
+       rc = stm32_firewall_controller_register(etzpc_controller);
+       if (rc) {
+               dev_err(etzpc_controller->dev, "Couldn't register as a firewall controller: %d",
+                       rc);
+               return rc;
+       }
+
+       rc = stm32_firewall_populate_bus(etzpc_controller);
+       if (rc) {
+               dev_err(etzpc_controller->dev, "Couldn't populate ETZPC bus: %d",
+                       rc);
+               return rc;
+       }
+
+       /* Populate all allowed nodes */
+       return of_platform_populate(np, NULL, NULL, &pdev->dev);
+}
+
+static const struct of_device_id stm32_etzpc_of_match[] = {
+       { .compatible = "st,stm32-etzpc" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, stm32_etzpc_of_match);
+
+static struct platform_driver stm32_etzpc_driver = {
+       .probe  = stm32_etzpc_probe,
+       .driver = {
+               .name = "stm32-etzpc",
+               .of_match_table = stm32_etzpc_of_match,
+       },
+};
+module_platform_driver(stm32_etzpc_driver);
+
+MODULE_AUTHOR("Gatien Chevallier <gatien.chevallier@foss.st.com>");
+MODULE_DESCRIPTION("STMicroelectronics ETZPC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/bus/stm32_firewall.c b/drivers/bus/stm32_firewall.c
new file mode 100644 (file)
index 0000000..2fc9761
--- /dev/null
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/bus/stm32_firewall_device.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "stm32_firewall.h"
+
+/* Corresponds to STM32_FIREWALL_MAX_EXTRA_ARGS + firewall ID */
+#define STM32_FIREWALL_MAX_ARGS                (STM32_FIREWALL_MAX_EXTRA_ARGS + 1)
+
+static LIST_HEAD(firewall_controller_list);
+static DEFINE_MUTEX(firewall_controller_list_lock);
+
+/* Firewall device API */
+
+int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
+                               unsigned int nb_firewall)
+{
+       struct stm32_firewall_controller *ctrl;
+       struct of_phandle_iterator it;
+       unsigned int i, j = 0;
+       int err;
+
+       if (!firewall || !nb_firewall)
+               return -EINVAL;
+
+       /* Parse property with phandle parsed out */
+       of_for_each_phandle(&it, err, np, "access-controllers", "#access-controller-cells", 0) {
+               struct of_phandle_args provider_args;
+               struct device_node *provider = it.node;
+               const char *fw_entry;
+               bool match = false;
+
+               if (err) {
+                       pr_err("Unable to get access-controllers property for node %s\n, err: %d",
+                              np->full_name, err);
+                       of_node_put(provider);
+                       return err;
+               }
+
+               if (j >= nb_firewall) {
+                       pr_err("Too many firewall controllers");
+                       of_node_put(provider);
+                       return -EINVAL;
+               }
+
+               provider_args.args_count = of_phandle_iterator_args(&it, provider_args.args,
+                                                                   STM32_FIREWALL_MAX_ARGS);
+
+               /* Check if the parsed phandle corresponds to a registered firewall controller */
+               mutex_lock(&firewall_controller_list_lock);
+               list_for_each_entry(ctrl, &firewall_controller_list, entry) {
+                       if (ctrl->dev->of_node->phandle == it.phandle) {
+                               match = true;
+                               firewall[j].firewall_ctrl = ctrl;
+                               break;
+                       }
+               }
+               mutex_unlock(&firewall_controller_list_lock);
+
+               if (!match) {
+                       firewall[j].firewall_ctrl = NULL;
+                       pr_err("No firewall controller registered for %s\n", np->full_name);
+                       of_node_put(provider);
+                       return -ENODEV;
+               }
+
+               err = of_property_read_string_index(np, "access-controller-names", j, &fw_entry);
+               if (err == 0)
+                       firewall[j].entry = fw_entry;
+
+               /* Handle the case when there are no arguments given along with the phandle */
+               if (provider_args.args_count < 0 ||
+                   provider_args.args_count > STM32_FIREWALL_MAX_ARGS) {
+                       of_node_put(provider);
+                       return -EINVAL;
+               } else if (provider_args.args_count == 0) {
+                       firewall[j].extra_args_size = 0;
+                       firewall[j].firewall_id = U32_MAX;
+                       j++;
+                       continue;
+               }
+
+               /* The firewall ID is always the first argument */
+               firewall[j].firewall_id = provider_args.args[0];
+
+               /* Extra args start at the second argument */
+               for (i = 0; i < provider_args.args_count - 1; i++)
+                       firewall[j].extra_args[i] = provider_args.args[i + 1];
+
+               /* Remove the firewall ID arg that is not an extra argument */
+               firewall[j].extra_args_size = provider_args.args_count - 1;
+
+               j++;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_get_firewall);
+
+int stm32_firewall_grant_access(struct stm32_firewall *firewall)
+{
+       struct stm32_firewall_controller *firewall_controller;
+
+       if (!firewall || firewall->firewall_id == U32_MAX)
+               return -EINVAL;
+
+       firewall_controller = firewall->firewall_ctrl;
+
+       if (!firewall_controller)
+               return -ENODEV;
+
+       return firewall_controller->grant_access(firewall_controller, firewall->firewall_id);
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_grant_access);
+
+int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
+{
+       struct stm32_firewall_controller *firewall_controller;
+
+       if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX)
+               return -EINVAL;
+
+       firewall_controller = firewall->firewall_ctrl;
+
+       if (!firewall_controller)
+               return -ENODEV;
+
+       return firewall_controller->grant_access(firewall_controller, subsystem_id);
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_grant_access_by_id);
+
+void stm32_firewall_release_access(struct stm32_firewall *firewall)
+{
+       struct stm32_firewall_controller *firewall_controller;
+
+       if (!firewall || firewall->firewall_id == U32_MAX) {
+               pr_debug("Incorrect arguments when releasing a firewall access\n");
+               return;
+       }
+
+       firewall_controller = firewall->firewall_ctrl;
+
+       if (!firewall_controller) {
+               pr_debug("No firewall controller to release\n");
+               return;
+       }
+
+       firewall_controller->release_access(firewall_controller, firewall->firewall_id);
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_release_access);
+
+void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
+{
+       struct stm32_firewall_controller *firewall_controller;
+
+       if (!firewall || subsystem_id == U32_MAX || firewall->firewall_id == U32_MAX) {
+               pr_debug("Incorrect arguments when releasing a firewall access");
+               return;
+       }
+
+       firewall_controller = firewall->firewall_ctrl;
+
+       if (!firewall_controller) {
+               pr_debug("No firewall controller to release");
+               return;
+       }
+
+       firewall_controller->release_access(firewall_controller, subsystem_id);
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_release_access_by_id);
+
+/* Firewall controller API */
+
+int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller)
+{
+       struct stm32_firewall_controller *ctrl;
+
+       if (!firewall_controller)
+               return -ENODEV;
+
+       pr_info("Registering %s firewall controller\n", firewall_controller->name);
+
+       mutex_lock(&firewall_controller_list_lock);
+       list_for_each_entry(ctrl, &firewall_controller_list, entry) {
+               if (ctrl == firewall_controller) {
+                       pr_debug("%s firewall controller already registered\n",
+                                firewall_controller->name);
+                       mutex_unlock(&firewall_controller_list_lock);
+                       return 0;
+               }
+       }
+       list_add_tail(&firewall_controller->entry, &firewall_controller_list);
+       mutex_unlock(&firewall_controller_list_lock);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_controller_register);
+
+void stm32_firewall_controller_unregister(struct stm32_firewall_controller *firewall_controller)
+{
+       struct stm32_firewall_controller *ctrl;
+       bool controller_removed = false;
+
+       if (!firewall_controller) {
+               pr_debug("Null reference while unregistering firewall controller\n");
+               return;
+       }
+
+       mutex_lock(&firewall_controller_list_lock);
+       list_for_each_entry(ctrl, &firewall_controller_list, entry) {
+               if (ctrl == firewall_controller) {
+                       controller_removed = true;
+                       list_del_init(&ctrl->entry);
+                       break;
+               }
+       }
+       mutex_unlock(&firewall_controller_list_lock);
+
+       if (!controller_removed)
+               pr_debug("There was no firewall controller named %s to unregister\n",
+                        firewall_controller->name);
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_controller_unregister);
+
+int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_controller)
+{
+       struct stm32_firewall *firewalls;
+       struct device_node *child;
+       struct device *parent;
+       unsigned int i;
+       int len;
+       int err;
+
+       parent = firewall_controller->dev;
+
+       dev_dbg(parent, "Populating %s system bus\n", dev_name(firewall_controller->dev));
+
+       for_each_available_child_of_node(dev_of_node(parent), child) {
+               /* The access-controllers property is mandatory for firewall bus devices */
+               len = of_count_phandle_with_args(child, "access-controllers",
+                                                "#access-controller-cells");
+               if (len <= 0) {
+                       of_node_put(child);
+                       return -EINVAL;
+               }
+
+               firewalls = kcalloc(len, sizeof(*firewalls), GFP_KERNEL);
+               if (!firewalls) {
+                       of_node_put(child);
+                       return -ENOMEM;
+               }
+
+               err = stm32_firewall_get_firewall(child, firewalls, (unsigned int)len);
+               if (err) {
+                       kfree(firewalls);
+                       of_node_put(child);
+                       return err;
+               }
+
+               for (i = 0; i < len; i++) {
+                       if (firewall_controller->grant_access(firewall_controller,
+                                                             firewalls[i].firewall_id)) {
+                               /*
+                                * Peripheral access not allowed or not defined.
+                                * Mark the node as populated so platform bus won't probe it
+                                */
+                               of_detach_node(child);
+                               dev_err(parent, "%s: Device driver will not be probed\n",
+                                       child->full_name);
+                       }
+               }
+
+               kfree(firewalls);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(stm32_firewall_populate_bus);
diff --git a/drivers/bus/stm32_firewall.h b/drivers/bus/stm32_firewall.h
new file mode 100644 (file)
index 0000000..e5fac85
--- /dev/null
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _STM32_FIREWALL_H
+#define _STM32_FIREWALL_H
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+/**
+ * STM32_PERIPHERAL_FIREWALL:          This type of firewall protects peripherals
+ * STM32_MEMORY_FIREWALL:              This type of firewall protects memories/subsets of memory
+ *                                     zones
+ * STM32_NOTYPE_FIREWALL:              Undefined firewall type
+ */
+
+#define STM32_PERIPHERAL_FIREWALL      BIT(1)
+#define STM32_MEMORY_FIREWALL          BIT(2)
+#define STM32_NOTYPE_FIREWALL          BIT(3)
+
+/**
+ * struct stm32_firewall_controller - Information on firewall controller supplying services
+ *
+ * @name:                      Name of the firewall controller
+ * @dev:                       Device reference of the firewall controller
+ * @mmio:                      Base address of the firewall controller
+ * @entry:                     List entry of the firewall controller list
+ * @type:                      Type of firewall
+ * @max_entries:               Number of entries covered by the firewall
+ * @grant_access:              Callback used to grant access for a device access against a
+ *                             firewall controller
+ * @release_access:            Callback used to release resources taken by a device when access was
+ *                             granted
+ * @grant_memory_range_access: Callback used to grant access for a device to a given memory region
+ */
+struct stm32_firewall_controller {
+       const char *name;
+       struct device *dev;
+       void __iomem *mmio;
+       struct list_head entry;
+       unsigned int type;
+       unsigned int max_entries;
+
+       int (*grant_access)(struct stm32_firewall_controller *ctrl, u32 id);
+       void (*release_access)(struct stm32_firewall_controller *ctrl, u32 id);
+       int (*grant_memory_range_access)(struct stm32_firewall_controller *ctrl, phys_addr_t paddr,
+                                        size_t size);
+};
+
+/**
+ * stm32_firewall_controller_register - Register a firewall controller to the STM32 firewall
+ *                                     framework
+ * @firewall_controller:       Firewall controller to register
+ *
+ * Returns 0 in case of success or -ENODEV if no controller was given.
+ */
+int stm32_firewall_controller_register(struct stm32_firewall_controller *firewall_controller);
+
+/**
+ * stm32_firewall_controller_unregister - Unregister a firewall controller from the STM32
+ *                                       firewall framework
+ * @firewall_controller:       Firewall controller to unregister
+ */
+void stm32_firewall_controller_unregister(struct stm32_firewall_controller *firewall_controller);
+
+/**
+ * stm32_firewall_populate_bus - Populate device tree nodes that have a correct firewall
+ *                              configuration. This is used at boot-time only, as a sanity check
+ *                              between device tree and firewalls hardware configurations to
+ *                              prevent a kernel crash when a device driver is not granted access
+ *
+ * @firewall_controller:       Firewall controller which nodes will be populated or not
+ *
+ * Returns 0 in case of success or appropriate errno code if error occurred.
+ */
+int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_controller);
+
+#endif /* _STM32_FIREWALL_H */
diff --git a/drivers/bus/stm32_rifsc.c b/drivers/bus/stm32_rifsc.c
new file mode 100644 (file)
index 0000000..4cf1b60
--- /dev/null
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "stm32_firewall.h"
+
+/*
+ * RIFSC offset register
+ */
+#define RIFSC_RISC_SECCFGR0            0x10
+#define RIFSC_RISC_PRIVCFGR0           0x30
+#define RIFSC_RISC_PER0_CIDCFGR                0x100
+#define RIFSC_RISC_PER0_SEMCR          0x104
+#define RIFSC_RISC_HWCFGR2             0xFEC
+
+/*
+ * SEMCR register
+ */
+#define SEMCR_MUTEX                    BIT(0)
+
+/*
+ * HWCFGR2 register
+ */
+#define HWCFGR2_CONF1_MASK             GENMASK(15, 0)
+#define HWCFGR2_CONF2_MASK             GENMASK(23, 16)
+#define HWCFGR2_CONF3_MASK             GENMASK(31, 24)
+
+/*
+ * RIFSC miscellaneous
+ */
+#define RIFSC_RISC_CFEN_MASK           BIT(0)
+#define RIFSC_RISC_SEM_EN_MASK         BIT(1)
+#define RIFSC_RISC_SCID_MASK           GENMASK(6, 4)
+#define RIFSC_RISC_SEML_SHIFT          16
+#define RIFSC_RISC_SEMWL_MASK          GENMASK(23, 16)
+#define RIFSC_RISC_PER_ID_MASK         GENMASK(31, 24)
+
+#define RIFSC_RISC_PERx_CID_MASK       (RIFSC_RISC_CFEN_MASK | \
+                                        RIFSC_RISC_SEM_EN_MASK | \
+                                        RIFSC_RISC_SCID_MASK | \
+                                        RIFSC_RISC_SEMWL_MASK)
+
+#define IDS_PER_RISC_SEC_PRIV_REGS     32
+
+/* RIF miscellaneous */
+/*
+ * CIDCFGR register fields
+ */
+#define CIDCFGR_CFEN                   BIT(0)
+#define CIDCFGR_SEMEN                  BIT(1)
+#define CIDCFGR_SEMWL(x)               BIT(RIFSC_RISC_SEML_SHIFT + (x))
+
+#define SEMWL_SHIFT                    16
+
+/* Compartiment IDs */
+#define RIF_CID0                       0x0
+#define RIF_CID1                       0x1
+
+static bool stm32_rifsc_is_semaphore_available(void __iomem *addr)
+{
+       return !(readl(addr) & SEMCR_MUTEX);
+}
+
+static int stm32_rif_acquire_semaphore(struct stm32_firewall_controller *stm32_firewall_controller,
+                                      int id)
+{
+       void __iomem *addr = stm32_firewall_controller->mmio + RIFSC_RISC_PER0_SEMCR + 0x8 * id;
+
+       writel(SEMCR_MUTEX, addr);
+
+       /* Check that CID1 has the semaphore */
+       if (stm32_rifsc_is_semaphore_available(addr) ||
+           FIELD_GET(RIFSC_RISC_SCID_MASK, readl(addr)) != RIF_CID1)
+               return -EACCES;
+
+       return 0;
+}
+
+static void stm32_rif_release_semaphore(struct stm32_firewall_controller *stm32_firewall_controller,
+                                       int id)
+{
+       void __iomem *addr = stm32_firewall_controller->mmio + RIFSC_RISC_PER0_SEMCR + 0x8 * id;
+
+       if (stm32_rifsc_is_semaphore_available(addr))
+               return;
+
+       writel(SEMCR_MUTEX, addr);
+
+       /* Ok if another compartment takes the semaphore before the check */
+       WARN_ON(!stm32_rifsc_is_semaphore_available(addr) &&
+               FIELD_GET(RIFSC_RISC_SCID_MASK, readl(addr)) == RIF_CID1);
+}
+
+static int stm32_rifsc_grant_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
+{
+       struct stm32_firewall_controller *rifsc_controller = ctrl;
+       u32 reg_offset, reg_id, sec_reg_value, cid_reg_value;
+       int rc;
+
+       if (firewall_id >= rifsc_controller->max_entries) {
+               dev_err(rifsc_controller->dev, "Invalid sys bus ID %u", firewall_id);
+               return -EINVAL;
+       }
+
+       /*
+        * RIFSC_RISC_PRIVCFGRx and RIFSC_RISC_SECCFGRx both handle configuration access for
+        * 32 peripherals. On the other hand, there is one _RIFSC_RISC_PERx_CIDCFGR register
+        * per peripheral
+        */
+       reg_id = firewall_id / IDS_PER_RISC_SEC_PRIV_REGS;
+       reg_offset = firewall_id % IDS_PER_RISC_SEC_PRIV_REGS;
+       sec_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id);
+       cid_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * firewall_id);
+
+       /* First check conditions for semaphore mode, which doesn't take into account static CID. */
+       if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
+               if (cid_reg_value & BIT(RIF_CID1 + SEMWL_SHIFT)) {
+                       /* Static CID is irrelevant if semaphore mode */
+                       goto skip_cid_check;
+               } else {
+                       dev_dbg(rifsc_controller->dev,
+                               "Invalid bus semaphore configuration: index %d\n", firewall_id);
+                       return -EACCES;
+               }
+       }
+
+       /*
+        * Skip CID check if CID filtering isn't enabled or filtering is enabled on CID0, which
+        * corresponds to whatever CID.
+        */
+       if (!(cid_reg_value & CIDCFGR_CFEN) ||
+           FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0)
+               goto skip_cid_check;
+
+       /* Coherency check with the CID configuration */
+       if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
+               dev_dbg(rifsc_controller->dev, "Invalid CID configuration for peripheral: %d\n",
+                       firewall_id);
+               return -EACCES;
+       }
+
+skip_cid_check:
+       /* Check security configuration */
+       if (sec_reg_value & BIT(reg_offset)) {
+               dev_dbg(rifsc_controller->dev,
+                       "Invalid security configuration for peripheral: %d\n", firewall_id);
+               return -EACCES;
+       }
+
+       /*
+        * If the peripheral is in semaphore mode, take the semaphore so that
+        * the CID1 has the ownership.
+        */
+       if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
+               rc = stm32_rif_acquire_semaphore(rifsc_controller, firewall_id);
+               if (rc) {
+                       dev_err(rifsc_controller->dev,
+                               "Couldn't acquire semaphore for peripheral: %d\n", firewall_id);
+                       return rc;
+               }
+       }
+
+       return 0;
+}
+
+static void stm32_rifsc_release_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
+{
+       stm32_rif_release_semaphore(ctrl, firewall_id);
+}
+
+static int stm32_rifsc_probe(struct platform_device *pdev)
+{
+       struct stm32_firewall_controller *rifsc_controller;
+       struct device_node *np = pdev->dev.of_node;
+       u32 nb_risup, nb_rimu, nb_risal;
+       struct resource *res;
+       void __iomem *mmio;
+       int rc;
+
+       rifsc_controller = devm_kzalloc(&pdev->dev, sizeof(*rifsc_controller), GFP_KERNEL);
+       if (!rifsc_controller)
+               return -ENOMEM;
+
+       mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(mmio))
+               return PTR_ERR(mmio);
+
+       rifsc_controller->dev = &pdev->dev;
+       rifsc_controller->mmio = mmio;
+       rifsc_controller->name = dev_driver_string(rifsc_controller->dev);
+       rifsc_controller->type = STM32_PERIPHERAL_FIREWALL | STM32_MEMORY_FIREWALL;
+       rifsc_controller->grant_access = stm32_rifsc_grant_access;
+       rifsc_controller->release_access = stm32_rifsc_release_access;
+
+       /* Get number of RIFSC entries*/
+       nb_risup = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF1_MASK;
+       nb_rimu = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF2_MASK;
+       nb_risal = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF3_MASK;
+       rifsc_controller->max_entries = nb_risup + nb_rimu + nb_risal;
+
+       platform_set_drvdata(pdev, rifsc_controller);
+
+       rc = stm32_firewall_controller_register(rifsc_controller);
+       if (rc) {
+               dev_err(rifsc_controller->dev, "Couldn't register as a firewall controller: %d",
+                       rc);
+               return rc;
+       }
+
+       rc = stm32_firewall_populate_bus(rifsc_controller);
+       if (rc) {
+               dev_err(rifsc_controller->dev, "Couldn't populate RIFSC bus: %d",
+                       rc);
+               return rc;
+       }
+
+       /* Populate all allowed nodes */
+       return of_platform_populate(np, NULL, NULL, &pdev->dev);
+}
+
+static const struct of_device_id stm32_rifsc_of_match[] = {
+       { .compatible = "st,stm32mp25-rifsc" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, stm32_rifsc_of_match);
+
+static struct platform_driver stm32_rifsc_driver = {
+       .probe  = stm32_rifsc_probe,
+       .driver = {
+               .name = "stm32-rifsc",
+               .of_match_table = stm32_rifsc_of_match,
+       },
+};
+module_platform_driver(stm32_rifsc_driver);
+
+MODULE_AUTHOR("Gatien Chevallier <gatien.chevallier@foss.st.com>");
+MODULE_DESCRIPTION("STMicroelectronics RIFSC driver");
+MODULE_LICENSE("GPL");
index 41d33f39efe52a55347b8203bacfd618f849ebc4..8767e04d6c89738b21f1fbf091bd8f77f1c431ae 100644 (file)
@@ -1,6 +1,17 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * ti-sysc.c - Texas Instruments sysc interconnect target driver
+ *
+ * TI SoCs have an interconnect target wrapper IP for many devices. The wrapper
+ * IP manages clock gating, resets, and PM capabilities for the connected devices.
+ *
+ * Copyright (C) 2017-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Many features are based on the earlier omap_hwmod arch code with thanks to all
+ * the people who developed and debugged the code over the years:
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011-2021 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #include <linux/io.h>
@@ -1458,8 +1469,7 @@ static int __maybe_unused sysc_noirq_suspend(struct device *dev)
 
        ddata = dev_get_drvdata(dev);
 
-       if (ddata->cfg.quirks &
-           (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
+       if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
                return 0;
 
        if (!ddata->enabled)
@@ -1477,8 +1487,7 @@ static int __maybe_unused sysc_noirq_resume(struct device *dev)
 
        ddata = dev_get_drvdata(dev);
 
-       if (ddata->cfg.quirks &
-           (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE))
+       if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
                return 0;
 
        if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_RESUME) {
@@ -1529,19 +1538,6 @@ struct sysc_revision_quirk {
        }
 
 static const struct sysc_revision_quirk sysc_revision_quirks[] = {
-       /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-       /* Uarts on omap4 and later */
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
-                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
-                  SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE),
-
        /* Quirks that need to be set based on the module address */
        SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff,
                   SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT |
@@ -1599,6 +1595,17 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
                   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
        SYSC_QUIRK("sata", 0, 0xfc, 0x1100, -ENODEV, 0x5e412000, 0xffffffff,
                   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT),
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT),
+       /* Uarts on omap4 and later */
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff,
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT),
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT),
+       SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff,
+                  SYSC_QUIRK_SWSUP_SIDLE_ACT),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff,
                   SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff,
@@ -2145,8 +2152,7 @@ static int sysc_reset(struct sysc *ddata)
        sysc_offset = ddata->offsets[SYSC_SYSCONFIG];
 
        if (ddata->legacy_mode ||
-           ddata->cap->regbits->srst_shift < 0 ||
-           ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
+           ddata->cap->regbits->srst_shift < 0)
                return 0;
 
        sysc_mask = BIT(ddata->cap->regbits->srst_shift);
@@ -2240,12 +2246,14 @@ static int sysc_init_module(struct sysc *ddata)
                        goto err_main_clocks;
        }
 
-       error = sysc_reset(ddata);
-       if (error)
-               dev_err(ddata->dev, "Reset failed with %d\n", error);
+       if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
+               error = sysc_reset(ddata);
+               if (error)
+                       dev_err(ddata->dev, "Reset failed with %d\n", error);
 
-       if (error && !ddata->legacy_mode)
-               sysc_disable_module(ddata->dev);
+               if (error && !ddata->legacy_mode)
+                       sysc_disable_module(ddata->dev);
+       }
 
 err_main_clocks:
        if (error)
@@ -2447,89 +2455,6 @@ static int __maybe_unused sysc_child_runtime_resume(struct device *dev)
        return pm_generic_runtime_resume(dev);
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int sysc_child_suspend_noirq(struct device *dev)
-{
-       struct sysc *ddata;
-       int error;
-
-       ddata = sysc_child_to_parent(dev);
-
-       dev_dbg(ddata->dev, "%s %s\n", __func__,
-               ddata->name ? ddata->name : "");
-
-       error = pm_generic_suspend_noirq(dev);
-       if (error) {
-               dev_err(dev, "%s error at %i: %i\n",
-                       __func__, __LINE__, error);
-
-               return error;
-       }
-
-       if (!pm_runtime_status_suspended(dev)) {
-               error = pm_generic_runtime_suspend(dev);
-               if (error) {
-                       dev_dbg(dev, "%s busy at %i: %i\n",
-                               __func__, __LINE__, error);
-
-                       return 0;
-               }
-
-               error = sysc_runtime_suspend(ddata->dev);
-               if (error) {
-                       dev_err(dev, "%s error at %i: %i\n",
-                               __func__, __LINE__, error);
-
-                       return error;
-               }
-
-               ddata->child_needs_resume = true;
-       }
-
-       return 0;
-}
-
-static int sysc_child_resume_noirq(struct device *dev)
-{
-       struct sysc *ddata;
-       int error;
-
-       ddata = sysc_child_to_parent(dev);
-
-       dev_dbg(ddata->dev, "%s %s\n", __func__,
-               ddata->name ? ddata->name : "");
-
-       if (ddata->child_needs_resume) {
-               ddata->child_needs_resume = false;
-
-               error = sysc_runtime_resume(ddata->dev);
-               if (error)
-                       dev_err(ddata->dev,
-                               "%s runtime resume error: %i\n",
-                               __func__, error);
-
-               error = pm_generic_runtime_resume(dev);
-               if (error)
-                       dev_err(ddata->dev,
-                               "%s generic runtime resume: %i\n",
-                               __func__, error);
-       }
-
-       return pm_generic_resume_noirq(dev);
-}
-#endif
-
-static struct dev_pm_domain sysc_child_pm_domain = {
-       .ops = {
-               SET_RUNTIME_PM_OPS(sysc_child_runtime_suspend,
-                                  sysc_child_runtime_resume,
-                                  NULL)
-               USE_PLATFORM_PM_SLEEP_OPS
-               SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_child_suspend_noirq,
-                                             sysc_child_resume_noirq)
-       }
-};
-
 /* Caller needs to take list_lock if ever used outside of cpu_pm */
 static void sysc_reinit_modules(struct sysc_soc_info *soc)
 {
@@ -2600,25 +2525,6 @@ out_unlock:
        mutex_unlock(&sysc_soc->list_lock);
 }
 
-/**
- * sysc_legacy_idle_quirk - handle children in omap_device compatible way
- * @ddata: device driver data
- * @child: child device driver
- *
- * Allow idle for child devices as done with _od_runtime_suspend().
- * Otherwise many child devices will not idle because of the permanent
- * parent usecount set in pm_runtime_irq_safe().
- *
- * Note that the long term solution is to just modify the child device
- * drivers to not set pm_runtime_irq_safe() and then this can be just
- * dropped.
- */
-static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child)
-{
-       if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE)
-               dev_pm_domain_set(child, &sysc_child_pm_domain);
-}
-
 static int sysc_notifier_call(struct notifier_block *nb,
                              unsigned long event, void *device)
 {
@@ -2635,7 +2541,6 @@ static int sysc_notifier_call(struct notifier_block *nb,
                error = sysc_child_add_clocks(ddata, dev);
                if (error)
                        return error;
-               sysc_legacy_idle_quirk(ddata, dev);
                break;
        default:
                break;
@@ -2859,8 +2764,7 @@ static const struct sysc_capabilities sysc_34xx_sr = {
        .type = TI_SYSC_OMAP34XX_SR,
        .sysc_mask = SYSC_OMAP2_CLOCKACTIVITY,
        .regbits = &sysc_regbits_omap34xx_sr,
-       .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED |
-                     SYSC_QUIRK_LEGACY_IDLE,
+       .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED,
 };
 
 /*
@@ -2881,13 +2785,12 @@ static const struct sysc_capabilities sysc_36xx_sr = {
        .type = TI_SYSC_OMAP36XX_SR,
        .sysc_mask = SYSC_OMAP3_SR_ENAWAKEUP,
        .regbits = &sysc_regbits_omap36xx_sr,
-       .mod_quirks = SYSC_QUIRK_UNCACHED | SYSC_QUIRK_LEGACY_IDLE,
+       .mod_quirks = SYSC_QUIRK_UNCACHED,
 };
 
 static const struct sysc_capabilities sysc_omap4_sr = {
        .type = TI_SYSC_OMAP4_SR,
        .regbits = &sysc_regbits_omap36xx_sr,
-       .mod_quirks = SYSC_QUIRK_LEGACY_IDLE,
 };
 
 /*
index e9cc8b4786fbfb9eba5d3c1d8c06c3d08477a132..6874b72ec59d8d7ab3635fbc13213139adf9e32b 100644 (file)
@@ -290,7 +290,7 @@ static int __init sifive_ccache_init(void)
        struct device_node *np;
        struct resource res;
        const struct of_device_id *match;
-       unsigned long quirks;
+       unsigned long quirks __maybe_unused;
        int rc;
 
        np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match);
index c9bf2c219841846570c6cffefe8e2e4c59583997..f0d0c044731c0f6101975428b9791ccb3fd2a33a 100644 (file)
@@ -149,7 +149,7 @@ struct agp_bridge_driver alpha_core_agp_driver = {
 
 struct agp_bridge_data *alpha_bridge;
 
-int __init
+static int __init
 alpha_core_agp_setup(void)
 {
        alpha_agp_info *agp = alpha_mv.agp_info();
index 927088b2c3d3f2c60bd5c3fa9735ba90d2e0bdd3..e63a6a17793c8560085c1571e862338cf4e1c21b 100644 (file)
@@ -27,6 +27,20 @@ menuconfig TCG_TPM
 
 if TCG_TPM
 
+config TCG_TPM2_HMAC
+       bool "Use HMAC and encrypted transactions on the TPM bus"
+       default y
+       select CRYPTO_ECDH
+       select CRYPTO_LIB_AESCFB
+       select CRYPTO_LIB_SHA256
+       help
+         Setting this causes us to deploy a scheme which uses request
+         and response HMACs in addition to encryption for
+         communicating with the TPM to prevent or detect bus snooping
+         and interposer attacks (see tpm-security.rst).  Saying Y
+         here adds some encryption overhead to all kernel to TPM
+         transactions.
+
 config HW_RANDOM_TPM
        bool "TPM HW Random Number Generator support"
        depends on TCG_TPM && HW_RANDOM && !(TCG_TPM=y && HW_RANDOM=m)
@@ -149,6 +163,7 @@ config TCG_NSC
 config TCG_ATMEL
        tristate "Atmel TPM Interface"
        depends on PPC64 || HAS_IOPORT_MAP
+       depends on HAS_IOPORT
        help
          If you have a TPM security chip from Atmel say Yes and it 
          will be accessible from within Linux.  To compile this driver 
@@ -156,7 +171,7 @@ config TCG_ATMEL
 
 config TCG_INFINEON
        tristate "Infineon Technologies TPM Interface"
-       depends on PNP
+       depends on PNP || COMPILE_TEST
        help
          If you have a TPM security chip from Infineon Technologies
          (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it
index 0222b1ddb3105e6726fa93e2ea3500d404964cbc..4c695b0388f3eb204589bf372f51f6e8ac405ec5 100644 (file)
@@ -15,7 +15,9 @@ tpm-y += tpm-sysfs.o
 tpm-y += eventlog/common.o
 tpm-y += eventlog/tpm1.o
 tpm-y += eventlog/tpm2.o
+tpm-y += tpm-buf.o
 
+tpm-$(CONFIG_TCG_TPM2_HMAC) += tpm2-sessions.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o eventlog/acpi.o
 tpm-$(CONFIG_EFI) += eventlog/efi.o
 tpm-$(CONFIG_OF) += eventlog/of.o
index bd757d836c5cf9ba53b6355da877d5907e32a8e7..69533d0bfb51e8064efaabaf548b217e0e3be278 100644 (file)
@@ -142,7 +142,6 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
 
        log->bios_event_log_end = log->bios_event_log + len;
 
-       ret = -EIO;
        virt = acpi_os_map_iomem(start, len);
        if (!virt) {
                dev_warn(&chip->dev, "%s: Failed to map ACPI memory\n", __func__);
diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c
new file mode 100644 (file)
index 0000000..647c6ca
--- /dev/null
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Handling of TPM command and other buffers.
+ */
+
+#include <linux/tpm_command.h>
+#include <linux/module.h>
+#include <linux/tpm.h>
+
+/**
+ * tpm_buf_init() - Allocate and initialize a TPM command
+ * @buf:       A &tpm_buf
+ * @tag:       TPM_TAG_RQU_COMMAND, TPM2_ST_NO_SESSIONS or TPM2_ST_SESSIONS
+ * @ordinal:   A command ordinal
+ *
+ * Return: 0 or -ENOMEM
+ */
+int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
+{
+       buf->data = (u8 *)__get_free_page(GFP_KERNEL);
+       if (!buf->data)
+               return -ENOMEM;
+
+       tpm_buf_reset(buf, tag, ordinal);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_init);
+
+/**
+ * tpm_buf_reset() - Initialize a TPM command
+ * @buf:       A &tpm_buf
+ * @tag:       TPM_TAG_RQU_COMMAND, TPM2_ST_NO_SESSIONS or TPM2_ST_SESSIONS
+ * @ordinal:   A command ordinal
+ */
+void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+
+       WARN_ON(tag != TPM_TAG_RQU_COMMAND && tag != TPM2_ST_NO_SESSIONS &&
+               tag != TPM2_ST_SESSIONS && tag != 0);
+
+       buf->flags = 0;
+       buf->length = sizeof(*head);
+       head->tag = cpu_to_be16(tag);
+       head->length = cpu_to_be32(sizeof(*head));
+       head->ordinal = cpu_to_be32(ordinal);
+       buf->handles = 0;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_reset);
+
+/**
+ * tpm_buf_init_sized() - Allocate and initialize a sized (TPM2B) buffer
+ * @buf:       A @tpm_buf
+ *
+ * Return: 0 or -ENOMEM
+ */
+int tpm_buf_init_sized(struct tpm_buf *buf)
+{
+       buf->data = (u8 *)__get_free_page(GFP_KERNEL);
+       if (!buf->data)
+               return -ENOMEM;
+
+       tpm_buf_reset_sized(buf);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_init_sized);
+
+/**
+ * tpm_buf_reset_sized() - Initialize a sized buffer
+ * @buf:       A &tpm_buf
+ */
+void tpm_buf_reset_sized(struct tpm_buf *buf)
+{
+       buf->flags = TPM_BUF_TPM2B;
+       buf->length = 2;
+       buf->data[0] = 0;
+       buf->data[1] = 0;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_reset_sized);
+
+void tpm_buf_destroy(struct tpm_buf *buf)
+{
+       free_page((unsigned long)buf->data);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_destroy);
+
+/**
+ * tpm_buf_length() - Return the number of bytes consumed by the data
+ * @buf:       A &tpm_buf
+ *
+ * Return: The number of bytes consumed by the buffer
+ */
+u32 tpm_buf_length(struct tpm_buf *buf)
+{
+       return buf->length;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_length);
+
+/**
+ * tpm_buf_append() - Append data to an initialized buffer
+ * @buf:       A &tpm_buf
+ * @new_data:  A data blob
+ * @new_length:        Size of the appended data
+ */
+void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length)
+{
+       /* Return silently if overflow has already happened. */
+       if (buf->flags & TPM_BUF_OVERFLOW)
+               return;
+
+       if ((buf->length + new_length) > PAGE_SIZE) {
+               WARN(1, "tpm_buf: write overflow\n");
+               buf->flags |= TPM_BUF_OVERFLOW;
+               return;
+       }
+
+       memcpy(&buf->data[buf->length], new_data, new_length);
+       buf->length += new_length;
+
+       if (buf->flags & TPM_BUF_TPM2B)
+               ((__be16 *)buf->data)[0] = cpu_to_be16(buf->length - 2);
+       else
+               ((struct tpm_header *)buf->data)->length = cpu_to_be32(buf->length);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_append);
+
+void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value)
+{
+       tpm_buf_append(buf, &value, 1);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_append_u8);
+
+void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value)
+{
+       __be16 value2 = cpu_to_be16(value);
+
+       tpm_buf_append(buf, (u8 *)&value2, 2);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_append_u16);
+
+void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
+{
+       __be32 value2 = cpu_to_be32(value);
+
+       tpm_buf_append(buf, (u8 *)&value2, 4);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_append_u32);
+
+/**
+ * tpm_buf_read() - Read from a TPM buffer
+ * @buf:       &tpm_buf instance
+ * @offset:    offset within the buffer
+ * @count:     the number of bytes to read
+ * @output:    the output buffer
+ */
+static void tpm_buf_read(struct tpm_buf *buf, off_t *offset, size_t count, void *output)
+{
+       off_t next_offset;
+
+       /* Return silently if overflow has already happened. */
+       if (buf->flags & TPM_BUF_BOUNDARY_ERROR)
+               return;
+
+       next_offset = *offset + count;
+       if (next_offset > buf->length) {
+               WARN(1, "tpm_buf: read out of boundary\n");
+               buf->flags |= TPM_BUF_BOUNDARY_ERROR;
+               return;
+       }
+
+       memcpy(output, &buf->data[*offset], count);
+       *offset = next_offset;
+}
+
+/**
+ * tpm_buf_read_u8() - Read 8-bit word from a TPM buffer
+ * @buf:       &tpm_buf instance
+ * @offset:    offset within the buffer
+ *
+ * Return: next 8-bit word
+ */
+u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset)
+{
+       u8 value;
+
+       tpm_buf_read(buf, offset, sizeof(value), &value);
+
+       return value;
+}
+EXPORT_SYMBOL_GPL(tpm_buf_read_u8);
+
+/**
+ * tpm_buf_read_u16() - Read 16-bit word from a TPM buffer
+ * @buf:       &tpm_buf instance
+ * @offset:    offset within the buffer
+ *
+ * Return: next 16-bit word
+ */
+u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset)
+{
+       u16 value;
+
+       tpm_buf_read(buf, offset, sizeof(value), &value);
+
+       return be16_to_cpu(value);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_read_u16);
+
+/**
+ * tpm_buf_read_u32() - Read 32-bit word from a TPM buffer
+ * @buf:       &tpm_buf instance
+ * @offset:    offset within the buffer
+ *
+ * Return: next 32-bit word
+ */
+u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset)
+{
+       u32 value;
+
+       tpm_buf_read(buf, offset, sizeof(value), &value);
+
+       return be32_to_cpu(value);
+}
+EXPORT_SYMBOL_GPL(tpm_buf_read_u32);
+
+static u16 tpm_buf_tag(struct tpm_buf *buf)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+
+       return be16_to_cpu(head->tag);
+}
+
+/**
+ * tpm_buf_parameters - return the TPM response parameters area of the tpm_buf
+ * @buf: tpm_buf to use
+ *
+ * Where the parameters are located depends on the tag of a TPM
+ * command (it's immediately after the header for TPM_ST_NO_SESSIONS
+ * or 4 bytes after for TPM_ST_SESSIONS). Evaluate this and return a
+ * pointer to the first byte of the parameters area.
+ *
+ * @return: pointer to parameters area
+ */
+u8 *tpm_buf_parameters(struct tpm_buf *buf)
+{
+       int offset = TPM_HEADER_SIZE;
+
+       if (tpm_buf_tag(buf) == TPM2_ST_SESSIONS)
+               offset += 4;
+
+       return &buf->data[offset];
+}
index 42b1062e33cd5d81ec7cc3ca9f2baf694d8365da..854546000c92bfb16224633dfc36993716bb5464 100644 (file)
@@ -158,6 +158,9 @@ int tpm_try_get_ops(struct tpm_chip *chip)
 {
        int rc = -EIO;
 
+       if (chip->flags & TPM_CHIP_FLAG_DISABLE)
+               return rc;
+
        get_device(&chip->dev);
 
        down_read(&chip->ops_sem);
@@ -275,6 +278,9 @@ static void tpm_dev_release(struct device *dev)
        kfree(chip->work_space.context_buf);
        kfree(chip->work_space.session_buf);
        kfree(chip->allocated_banks);
+#ifdef CONFIG_TCG_TPM2_HMAC
+       kfree(chip->auth);
+#endif
        kfree(chip);
 }
 
index 757336324c904cf98451898d0f0ef37b33c7df80..5da134f12c9a470fb83f85574b46b6105466111a 100644 (file)
@@ -232,6 +232,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
        if (len < min_rsp_body_length + TPM_HEADER_SIZE)
                return -EFAULT;
 
+       buf->length = len;
        return 0;
 }
 EXPORT_SYMBOL_GPL(tpm_transmit_cmd);
@@ -342,31 +343,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(tpm_pcr_extend);
 
-/**
- * tpm_send - send a TPM command
- * @chip:      a &struct tpm_chip instance, %NULL for the default chip
- * @cmd:       a TPM command buffer
- * @buflen:    the length of the TPM command buffer
- *
- * Return: same as with tpm_transmit_cmd()
- */
-int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
-{
-       struct tpm_buf buf;
-       int rc;
-
-       chip = tpm_find_get_ops(chip);
-       if (!chip)
-               return -ENODEV;
-
-       buf.data = cmd;
-       rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to a send a command");
-
-       tpm_put_ops(chip);
-       return rc;
-}
-EXPORT_SYMBOL_GPL(tpm_send);
-
 int tpm_auto_startup(struct tpm_chip *chip)
 {
        int rc;
index 54c71473aa2965b1b118ed00be61693ae8718049..94231f052ea78be684aad737b7dbd04af7e9099e 100644 (file)
@@ -309,6 +309,21 @@ static ssize_t tpm_version_major_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(tpm_version_major);
 
+#ifdef CONFIG_TCG_TPM2_HMAC
+static ssize_t null_name_show(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct tpm_chip *chip = to_tpm_chip(dev);
+       int size = TPM2_NAME_SIZE;
+
+       bin2hex(buf, chip->null_key_name, size);
+       size *= 2;
+       buf[size++] = '\n';
+       return size;
+}
+static DEVICE_ATTR_RO(null_name);
+#endif
+
 static struct attribute *tpm1_dev_attrs[] = {
        &dev_attr_pubek.attr,
        &dev_attr_pcrs.attr,
@@ -326,6 +341,9 @@ static struct attribute *tpm1_dev_attrs[] = {
 
 static struct attribute *tpm2_dev_attrs[] = {
        &dev_attr_tpm_version_major.attr,
+#ifdef CONFIG_TCG_TPM2_HMAC
+       &dev_attr_null_name.attr,
+#endif
        NULL
 };
 
index 61445f1dc46df3f4f5780bd42f028c6fa91143a6..6b8b9956ba6944f651419a18b18bd2e4defab8b4 100644 (file)
@@ -312,9 +312,23 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
                      size_t *bufsiz);
 int tpm_devs_add(struct tpm_chip *chip);
 void tpm_devs_remove(struct tpm_chip *chip);
+int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
+                     unsigned int buf_size, unsigned int *offset);
+int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
+                     unsigned int *offset, u32 *handle);
 
 void tpm_bios_log_setup(struct tpm_chip *chip);
 void tpm_bios_log_teardown(struct tpm_chip *chip);
 int tpm_dev_common_init(void);
 void tpm_dev_common_exit(void);
+
+#ifdef CONFIG_TCG_TPM2_HMAC
+int tpm2_sessions_init(struct tpm_chip *chip);
+#else
+static inline int tpm2_sessions_init(struct tpm_chip *chip)
+{
+       return 0;
+}
+#endif
+
 #endif
index 93545be190a50d54fec136152d6ef23fa81e2be3..0cdf892ec2a7d40929787948dc146d432f74d70f 100644 (file)
@@ -216,13 +216,6 @@ out:
        return rc;
 }
 
-struct tpm2_null_auth_area {
-       __be32  handle;
-       __be16  nonce_size;
-       u8  attributes;
-       __be16  auth_size;
-} __packed;
-
 /**
  * tpm2_pcr_extend() - extend a PCR value
  *
@@ -236,24 +229,22 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
                    struct tpm_digest *digests)
 {
        struct tpm_buf buf;
-       struct tpm2_null_auth_area auth_area;
        int rc;
        int i;
 
-       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+       rc = tpm2_start_auth_session(chip);
        if (rc)
                return rc;
 
-       tpm_buf_append_u32(&buf, pcr_idx);
+       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+       if (rc) {
+               tpm2_end_auth_session(chip);
+               return rc;
+       }
 
-       auth_area.handle = cpu_to_be32(TPM2_RS_PW);
-       auth_area.nonce_size = 0;
-       auth_area.attributes = 0;
-       auth_area.auth_size = 0;
+       tpm_buf_append_name(chip, &buf, pcr_idx, NULL);
+       tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
 
-       tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area));
-       tpm_buf_append(&buf, (const unsigned char *)&auth_area,
-                      sizeof(auth_area));
        tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
 
        for (i = 0; i < chip->nr_allocated_banks; i++) {
@@ -262,7 +253,9 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
                               chip->allocated_banks[i].digest_size);
        }
 
+       tpm_buf_fill_hmac_session(chip, &buf);
        rc = tpm_transmit_cmd(chip, &buf, 0, "attempting extend a PCR value");
+       rc = tpm_buf_check_hmac_response(chip, &buf, rc);
 
        tpm_buf_destroy(&buf);
 
@@ -299,25 +292,35 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
        if (!num_bytes || max > TPM_MAX_RNG_DATA)
                return -EINVAL;
 
-       err = tpm_buf_init(&buf, 0, 0);
+       err = tpm2_start_auth_session(chip);
        if (err)
                return err;
 
+       err = tpm_buf_init(&buf, 0, 0);
+       if (err) {
+               tpm2_end_auth_session(chip);
+               return err;
+       }
+
        do {
-               tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM);
+               tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
+               tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT
+                                               | TPM2_SA_CONTINUE_SESSION,
+                                               NULL, 0);
                tpm_buf_append_u16(&buf, num_bytes);
+               tpm_buf_fill_hmac_session(chip, &buf);
                err = tpm_transmit_cmd(chip, &buf,
                                       offsetof(struct tpm2_get_random_out,
                                                buffer),
                                       "attempting get random");
+               err = tpm_buf_check_hmac_response(chip, &buf, err);
                if (err) {
                        if (err > 0)
                                err = -EIO;
                        goto out;
                }
 
-               out = (struct tpm2_get_random_out *)
-                       &buf.data[TPM_HEADER_SIZE];
+               out = (struct tpm2_get_random_out *)tpm_buf_parameters(&buf);
                recd = min_t(u32, be16_to_cpu(out->size), num_bytes);
                if (tpm_buf_length(&buf) <
                    TPM_HEADER_SIZE +
@@ -334,9 +337,12 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
        } while (retries-- && total < max);
 
        tpm_buf_destroy(&buf);
+       tpm2_end_auth_session(chip);
+
        return total ? total : -EIO;
 out:
        tpm_buf_destroy(&buf);
+       tpm2_end_auth_session(chip);
        return err;
 }
 
@@ -759,6 +765,11 @@ int tpm2_auto_startup(struct tpm_chip *chip)
                rc = 0;
        }
 
+       if (rc)
+               goto out;
+
+       rc = tpm2_sessions_init(chip);
+
 out:
        /*
         * Infineon TPM in field upgrade mode will return no data for the number
diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
new file mode 100644 (file)
index 0000000..ea88606
--- /dev/null
@@ -0,0 +1,1286 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (C) 2018 James.Bottomley@HansenPartnership.com
+ *
+ * Cryptographic helper routines for handling TPM2 sessions for
+ * authorization HMAC and request response encryption.
+ *
+ * The idea is to ensure that every TPM command is HMAC protected by a
+ * session, meaning in-flight tampering would be detected and in
+ * addition all sensitive inputs and responses should be encrypted.
+ *
+ * The basic way this works is to use a TPM feature called salted
+ * sessions where a random secret used in session construction is
+ * encrypted to the public part of a known TPM key.  The problem is we
+ * have no known keys, so initially a primary Elliptic Curve key is
+ * derived from the NULL seed (we use EC because most TPMs generate
+ * these keys much faster than RSA ones).  The curve used is NIST_P256
+ * because that's now mandated to be present in 'TCG TPM v2.0
+ * Provisioning Guidance'
+ *
+ * Threat problems: the initial TPM2_CreatePrimary is not (and cannot
+ * be) session protected, so a clever Man in the Middle could return a
+ * public key they control to this command and from there intercept
+ * and decode all subsequent session based transactions.  The kernel
+ * cannot mitigate this threat but, after boot, userspace can get
+ * proof this has not happened by asking the TPM to certify the NULL
+ * key.  This certification would chain back to the TPM Endorsement
+ * Certificate and prove the NULL seed primary had not been tampered
+ * with and thus all sessions must have been cryptographically secure.
+ * To assist with this, the initial NULL seed public key name is made
+ * available in a sysfs file.
+ *
+ * Use of these functions:
+ *
+ * The design is all the crypto, hash and hmac gunk is confined in this
+ * file and never needs to be seen even by the kernel internal user.  To
+ * the user there's an init function tpm2_sessions_init() that needs to
+ * be called once per TPM which generates the NULL seed primary key.
+ *
+ * These are the usage functions:
+ *
+ * tpm2_start_auth_session() which allocates the opaque auth structure
+ *     and gets a session from the TPM.  This must be called before
+ *     any of the following functions.  The session is protected by a
+ *     session_key which is derived from a random salt value
+ *     encrypted to the NULL seed.
+ * tpm2_end_auth_session() kills the session and frees the resources.
+ *     Under normal operation this function is done by
+ *     tpm_buf_check_hmac_response(), so this is only to be used on
+ *     error legs where the latter is not executed.
+ * tpm_buf_append_name() to add a handle to the buffer.  This must be
+ *     used in place of the usual tpm_buf_append_u32() for adding
+ *     handles because handles have to be processed specially when
+ *     calculating the HMAC.  In particular, for NV, volatile and
+ *     permanent objects you now need to provide the name.
+ * tpm_buf_append_hmac_session() which appends the hmac session to the
+ *     buf in the same way tpm_buf_append_auth does().
+ * tpm_buf_fill_hmac_session() This calculates the correct hash and
+ *     places it in the buffer.  It must be called after the complete
+ *     command buffer is finalized so it can fill in the correct HMAC
+ *     based on the parameters.
+ * tpm_buf_check_hmac_response() which checks the session response in
+ *     the buffer and calculates what it should be.  If there's a
+ *     mismatch it will log a warning and return an error.  If
+ *     tpm_buf_append_hmac_session() did not specify
+ *     TPM_SA_CONTINUE_SESSION then the session will be closed (if it
+ *     hasn't been consumed) and the auth structure freed.
+ */
+
+#include "tpm.h"
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <asm/unaligned.h>
+#include <crypto/kpp.h>
+#include <crypto/ecdh.h>
+#include <crypto/hash.h>
+#include <crypto/hmac.h>
+
+/* maximum number of names the TPM must remember for authorization */
+#define AUTH_MAX_NAMES 3
+
+static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
+                              u32 *handle, u8 *name);
+
+/*
+ * This is the structure that carries all the auth information (like
+ * session handle, nonces, session key and auth) from use to use it is
+ * designed to be opaque to anything outside.
+ */
+struct tpm2_auth {
+       u32 handle;
+       /*
+        * This has two meanings: before tpm_buf_fill_hmac_session()
+        * it marks the offset in the buffer of the start of the
+        * sessions (i.e. after all the handles).  Once the buffer has
+        * been filled it markes the session number of our auth
+        * session so we can find it again in the response buffer.
+        *
+        * The two cases are distinguished because the first offset
+        * must always be greater than TPM_HEADER_SIZE and the second
+        * must be less than or equal to 5.
+        */
+       u32 session;
+       /*
+        * the size here is variable and set by the size of our_nonce
+        * which must be between 16 and the name hash length. we set
+        * the maximum sha256 size for the greatest protection
+        */
+       u8 our_nonce[SHA256_DIGEST_SIZE];
+       u8 tpm_nonce[SHA256_DIGEST_SIZE];
+       /*
+        * the salt is only used across the session command/response
+        * after that it can be used as a scratch area
+        */
+       union {
+               u8 salt[EC_PT_SZ];
+               /* scratch for key + IV */
+               u8 scratch[AES_KEY_BYTES + AES_BLOCK_SIZE];
+       };
+       /*
+        * the session key and passphrase are the same size as the
+        * name digest (sha256 again).  The session key is constant
+        * for the use of the session and the passphrase can change
+        * with every invocation.
+        *
+        * Note: these fields must be adjacent and in this order
+        * because several HMAC/KDF schemes use the combination of the
+        * session_key and passphrase.
+        */
+       u8 session_key[SHA256_DIGEST_SIZE];
+       u8 passphrase[SHA256_DIGEST_SIZE];
+       int passphrase_len;
+       struct crypto_aes_ctx aes_ctx;
+       /* saved session attributes: */
+       u8 attrs;
+       __be32 ordinal;
+
+       /*
+        * memory for three authorization handles.  We know them by
+        * handle, but they are part of the session by name, which
+        * we must compute and remember
+        */
+       u32 name_h[AUTH_MAX_NAMES];
+       u8 name[AUTH_MAX_NAMES][2 + SHA512_DIGEST_SIZE];
+};
+
+/*
+ * Name Size based on TPM algorithm (assumes no hash bigger than 255)
+ */
+static u8 name_size(const u8 *name)
+{
+       static u8 size_map[] = {
+               [TPM_ALG_SHA1] = SHA1_DIGEST_SIZE,
+               [TPM_ALG_SHA256] = SHA256_DIGEST_SIZE,
+               [TPM_ALG_SHA384] = SHA384_DIGEST_SIZE,
+               [TPM_ALG_SHA512] = SHA512_DIGEST_SIZE,
+       };
+       u16 alg = get_unaligned_be16(name);
+       return size_map[alg] + 2;
+}
+
+/*
+ * It turns out the crypto hmac(sha256) is hard for us to consume
+ * because it assumes a fixed key and the TPM seems to change the key
+ * on every operation, so we weld the hmac init and final functions in
+ * here to give it the same usage characteristics as a regular hash
+ */
+static void tpm2_hmac_init(struct sha256_state *sctx, u8 *key, u32 key_len)
+{
+       u8 pad[SHA256_BLOCK_SIZE];
+       int i;
+
+       sha256_init(sctx);
+       for (i = 0; i < sizeof(pad); i++) {
+               if (i < key_len)
+                       pad[i] = key[i];
+               else
+                       pad[i] = 0;
+               pad[i] ^= HMAC_IPAD_VALUE;
+       }
+       sha256_update(sctx, pad, sizeof(pad));
+}
+
+static void tpm2_hmac_final(struct sha256_state *sctx, u8 *key, u32 key_len,
+                           u8 *out)
+{
+       u8 pad[SHA256_BLOCK_SIZE];
+       int i;
+
+       for (i = 0; i < sizeof(pad); i++) {
+               if (i < key_len)
+                       pad[i] = key[i];
+               else
+                       pad[i] = 0;
+               pad[i] ^= HMAC_OPAD_VALUE;
+       }
+
+       /* collect the final hash;  use out as temporary storage */
+       sha256_final(sctx, out);
+
+       sha256_init(sctx);
+       sha256_update(sctx, pad, sizeof(pad));
+       sha256_update(sctx, out, SHA256_DIGEST_SIZE);
+       sha256_final(sctx, out);
+}
+
+/*
+ * assume hash sha256 and nonces u, v of size SHA256_DIGEST_SIZE but
+ * otherwise standard tpm2_KDFa.  Note output is in bytes not bits.
+ */
+static void tpm2_KDFa(u8 *key, u32 key_len, const char *label, u8 *u,
+                     u8 *v, u32 bytes, u8 *out)
+{
+       u32 counter = 1;
+       const __be32 bits = cpu_to_be32(bytes * 8);
+
+       while (bytes > 0) {
+               struct sha256_state sctx;
+               __be32 c = cpu_to_be32(counter);
+
+               tpm2_hmac_init(&sctx, key, key_len);
+               sha256_update(&sctx, (u8 *)&c, sizeof(c));
+               sha256_update(&sctx, label, strlen(label)+1);
+               sha256_update(&sctx, u, SHA256_DIGEST_SIZE);
+               sha256_update(&sctx, v, SHA256_DIGEST_SIZE);
+               sha256_update(&sctx, (u8 *)&bits, sizeof(bits));
+               tpm2_hmac_final(&sctx, key, key_len, out);
+
+               bytes -= SHA256_DIGEST_SIZE;
+               counter++;
+               out += SHA256_DIGEST_SIZE;
+       }
+}
+
+/*
+ * Somewhat of a bastardization of the real KDFe.  We're assuming
+ * we're working with known point sizes for the input parameters and
+ * the hash algorithm is fixed at sha256.  Because we know that the
+ * point size is 32 bytes like the hash size, there's no need to loop
+ * in this KDF.
+ */
+static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v,
+                     u8 *out)
+{
+       struct sha256_state sctx;
+       /*
+        * this should be an iterative counter, but because we know
+        *  we're only taking 32 bytes for the point using a sha256
+        *  hash which is also 32 bytes, there's only one loop
+        */
+       __be32 c = cpu_to_be32(1);
+
+       sha256_init(&sctx);
+       /* counter (BE) */
+       sha256_update(&sctx, (u8 *)&c, sizeof(c));
+       /* secret value */
+       sha256_update(&sctx, z, EC_PT_SZ);
+       /* string including trailing zero */
+       sha256_update(&sctx, str, strlen(str)+1);
+       sha256_update(&sctx, pt_u, EC_PT_SZ);
+       sha256_update(&sctx, pt_v, EC_PT_SZ);
+       sha256_final(&sctx, out);
+}
+
+static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip)
+{
+       struct crypto_kpp *kpp;
+       struct kpp_request *req;
+       struct scatterlist s[2], d[1];
+       struct ecdh p = {0};
+       u8 encoded_key[EC_PT_SZ], *x, *y;
+       unsigned int buf_len;
+
+       /* secret is two sized points */
+       tpm_buf_append_u16(buf, (EC_PT_SZ + 2)*2);
+       /*
+        * we cheat here and append uninitialized data to form
+        * the points.  All we care about is getting the two
+        * co-ordinate pointers, which will be used to overwrite
+        * the uninitialized data
+        */
+       tpm_buf_append_u16(buf, EC_PT_SZ);
+       x = &buf->data[tpm_buf_length(buf)];
+       tpm_buf_append(buf, encoded_key, EC_PT_SZ);
+       tpm_buf_append_u16(buf, EC_PT_SZ);
+       y = &buf->data[tpm_buf_length(buf)];
+       tpm_buf_append(buf, encoded_key, EC_PT_SZ);
+       sg_init_table(s, 2);
+       sg_set_buf(&s[0], x, EC_PT_SZ);
+       sg_set_buf(&s[1], y, EC_PT_SZ);
+
+       kpp = crypto_alloc_kpp("ecdh-nist-p256", CRYPTO_ALG_INTERNAL, 0);
+       if (IS_ERR(kpp)) {
+               dev_err(&chip->dev, "crypto ecdh allocation failed\n");
+               return;
+       }
+
+       buf_len = crypto_ecdh_key_len(&p);
+       if (sizeof(encoded_key) < buf_len) {
+               dev_err(&chip->dev, "salt buffer too small needs %d\n",
+                       buf_len);
+               goto out;
+       }
+       crypto_ecdh_encode_key(encoded_key, buf_len, &p);
+       /* this generates a random private key */
+       crypto_kpp_set_secret(kpp, encoded_key, buf_len);
+
+       /* salt is now the public point of this private key */
+       req = kpp_request_alloc(kpp, GFP_KERNEL);
+       if (!req)
+               goto out;
+       kpp_request_set_input(req, NULL, 0);
+       kpp_request_set_output(req, s, EC_PT_SZ*2);
+       crypto_kpp_generate_public_key(req);
+       /*
+        * we're not done: now we have to compute the shared secret
+        * which is our private key multiplied by the tpm_key public
+        * point, we actually only take the x point and discard the y
+        * point and feed it through KDFe to get the final secret salt
+        */
+       sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ);
+       sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ);
+       kpp_request_set_input(req, s, EC_PT_SZ*2);
+       sg_init_one(d, chip->auth->salt, EC_PT_SZ);
+       kpp_request_set_output(req, d, EC_PT_SZ);
+       crypto_kpp_compute_shared_secret(req);
+       kpp_request_free(req);
+
+       /*
+        * pass the shared secret through KDFe for salt. Note salt
+        * area is used both for input shared secret and output salt.
+        * This works because KDFe fully consumes the secret before it
+        * writes the salt
+        */
+       tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x,
+                 chip->auth->salt);
+
+ out:
+       crypto_free_kpp(kpp);
+}
+
+/**
+ * tpm_buf_append_hmac_session() - Append a TPM session element
+ * @chip: the TPM chip structure
+ * @buf: The buffer to be appended
+ * @attributes: The session attributes
+ * @passphrase: The session authority (NULL if none)
+ * @passphrase_len: The length of the session authority (0 if none)
+ *
+ * This fills in a session structure in the TPM command buffer, except
+ * for the HMAC which cannot be computed until the command buffer is
+ * complete.  The type of session is controlled by the @attributes,
+ * the main ones of which are TPM2_SA_CONTINUE_SESSION which means the
+ * session won't terminate after tpm_buf_check_hmac_response(),
+ * TPM2_SA_DECRYPT which means this buffers first parameter should be
+ * encrypted with a session key and TPM2_SA_ENCRYPT, which means the
+ * response buffer's first parameter needs to be decrypted (confusing,
+ * but the defines are written from the point of view of the TPM).
+ *
+ * Any session appended by this command must be finalized by calling
+ * tpm_buf_fill_hmac_session() otherwise the HMAC will be incorrect
+ * and the TPM will reject the command.
+ *
+ * As with most tpm_buf operations, success is assumed because failure
+ * will be caused by an incorrect programming model and indicated by a
+ * kernel message.
+ */
+void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
+                                u8 attributes, u8 *passphrase,
+                                int passphrase_len)
+{
+       u8 nonce[SHA256_DIGEST_SIZE];
+       u32 len;
+       struct tpm2_auth *auth = chip->auth;
+
+       /*
+        * The Architecture Guide requires us to strip trailing zeros
+        * before computing the HMAC
+        */
+       while (passphrase && passphrase_len > 0
+              && passphrase[passphrase_len - 1] == '\0')
+               passphrase_len--;
+
+       auth->attrs = attributes;
+       auth->passphrase_len = passphrase_len;
+       if (passphrase_len)
+               memcpy(auth->passphrase, passphrase, passphrase_len);
+
+       if (auth->session != tpm_buf_length(buf)) {
+               /* we're not the first session */
+               len = get_unaligned_be32(&buf->data[auth->session]);
+               if (4 + len + auth->session != tpm_buf_length(buf)) {
+                       WARN(1, "session length mismatch, cannot append");
+                       return;
+               }
+
+               /* add our new session */
+               len += 9 + 2 * SHA256_DIGEST_SIZE;
+               put_unaligned_be32(len, &buf->data[auth->session]);
+       } else {
+               tpm_buf_append_u32(buf, 9 + 2 * SHA256_DIGEST_SIZE);
+       }
+
+       /* random number for our nonce */
+       get_random_bytes(nonce, sizeof(nonce));
+       memcpy(auth->our_nonce, nonce, sizeof(nonce));
+       tpm_buf_append_u32(buf, auth->handle);
+       /* our new nonce */
+       tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
+       tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
+       tpm_buf_append_u8(buf, auth->attrs);
+       /* and put a placeholder for the hmac */
+       tpm_buf_append_u16(buf, SHA256_DIGEST_SIZE);
+       tpm_buf_append(buf, nonce, SHA256_DIGEST_SIZE);
+}
+EXPORT_SYMBOL(tpm_buf_append_hmac_session);
+
+/**
+ * tpm_buf_fill_hmac_session() - finalize the session HMAC
+ * @chip: the TPM chip structure
+ * @buf: The buffer to be appended
+ *
+ * This command must not be called until all of the parameters have
+ * been appended to @buf otherwise the computed HMAC will be
+ * incorrect.
+ *
+ * This function computes and fills in the session HMAC using the
+ * session key and, if TPM2_SA_DECRYPT was specified, computes the
+ * encryption key and encrypts the first parameter of the command
+ * buffer with it.
+ *
+ * As with most tpm_buf operations, success is assumed because failure
+ * will be caused by an incorrect programming model and indicated by a
+ * kernel message.
+ */
+void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf)
+{
+       u32 cc, handles, val;
+       struct tpm2_auth *auth = chip->auth;
+       int i;
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+       off_t offset_s = TPM_HEADER_SIZE, offset_p;
+       u8 *hmac = NULL;
+       u32 attrs;
+       u8 cphash[SHA256_DIGEST_SIZE];
+       struct sha256_state sctx;
+
+       /* save the command code in BE format */
+       auth->ordinal = head->ordinal;
+
+       cc = be32_to_cpu(head->ordinal);
+
+       i = tpm2_find_cc(chip, cc);
+       if (i < 0) {
+               dev_err(&chip->dev, "Command 0x%x not found in TPM\n", cc);
+               return;
+       }
+       attrs = chip->cc_attrs_tbl[i];
+
+       handles = (attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0);
+
+       /*
+        * just check the names, it's easy to make mistakes.  This
+        * would happen if someone added a handle via
+        * tpm_buf_append_u32() instead of tpm_buf_append_name()
+        */
+       for (i = 0; i < handles; i++) {
+               u32 handle = tpm_buf_read_u32(buf, &offset_s);
+
+               if (auth->name_h[i] != handle) {
+                       dev_err(&chip->dev, "TPM: handle %d wrong for name\n",
+                                 i);
+                       return;
+               }
+       }
+       /* point offset_s to the start of the sessions */
+       val = tpm_buf_read_u32(buf, &offset_s);
+       /* point offset_p to the start of the parameters */
+       offset_p = offset_s + val;
+       for (i = 1; offset_s < offset_p; i++) {
+               u32 handle = tpm_buf_read_u32(buf, &offset_s);
+               u16 len;
+               u8 a;
+
+               /* nonce (already in auth) */
+               len = tpm_buf_read_u16(buf, &offset_s);
+               offset_s += len;
+
+               a = tpm_buf_read_u8(buf, &offset_s);
+
+               len = tpm_buf_read_u16(buf, &offset_s);
+               if (handle == auth->handle && auth->attrs == a) {
+                       hmac = &buf->data[offset_s];
+                       /*
+                        * save our session number so we know which
+                        * session in the response belongs to us
+                        */
+                       auth->session = i;
+               }
+
+               offset_s += len;
+       }
+       if (offset_s != offset_p) {
+               dev_err(&chip->dev, "TPM session length is incorrect\n");
+               return;
+       }
+       if (!hmac) {
+               dev_err(&chip->dev, "TPM could not find HMAC session\n");
+               return;
+       }
+
+       /* encrypt before HMAC */
+       if (auth->attrs & TPM2_SA_DECRYPT) {
+               u16 len;
+
+               /* need key and IV */
+               tpm2_KDFa(auth->session_key, SHA256_DIGEST_SIZE
+                         + auth->passphrase_len, "CFB", auth->our_nonce,
+                         auth->tpm_nonce, AES_KEY_BYTES + AES_BLOCK_SIZE,
+                         auth->scratch);
+
+               len = tpm_buf_read_u16(buf, &offset_p);
+               aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEY_BYTES);
+               aescfb_encrypt(&auth->aes_ctx, &buf->data[offset_p],
+                              &buf->data[offset_p], len,
+                              auth->scratch + AES_KEY_BYTES);
+               /* reset p to beginning of parameters for HMAC */
+               offset_p -= 2;
+       }
+
+       sha256_init(&sctx);
+       /* ordinal is already BE */
+       sha256_update(&sctx, (u8 *)&head->ordinal, sizeof(head->ordinal));
+       /* add the handle names */
+       for (i = 0; i < handles; i++) {
+               enum tpm2_mso_type mso = tpm2_handle_mso(auth->name_h[i]);
+
+               if (mso == TPM2_MSO_PERSISTENT ||
+                   mso == TPM2_MSO_VOLATILE ||
+                   mso == TPM2_MSO_NVRAM) {
+                       sha256_update(&sctx, auth->name[i],
+                                     name_size(auth->name[i]));
+               } else {
+                       __be32 h = cpu_to_be32(auth->name_h[i]);
+
+                       sha256_update(&sctx, (u8 *)&h, 4);
+               }
+       }
+       if (offset_s != tpm_buf_length(buf))
+               sha256_update(&sctx, &buf->data[offset_s],
+                             tpm_buf_length(buf) - offset_s);
+       sha256_final(&sctx, cphash);
+
+       /* now calculate the hmac */
+       tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
+                      + auth->passphrase_len);
+       sha256_update(&sctx, cphash, sizeof(cphash));
+       sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
+       sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
+       sha256_update(&sctx, &auth->attrs, 1);
+       tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
+                       + auth->passphrase_len, hmac);
+}
+EXPORT_SYMBOL(tpm_buf_fill_hmac_session);
+
+static int tpm2_parse_read_public(char *name, struct tpm_buf *buf)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+       off_t offset = TPM_HEADER_SIZE;
+       u32 tot_len = be32_to_cpu(head->length);
+       u32 val;
+
+       /* we're starting after the header so adjust the length */
+       tot_len -= TPM_HEADER_SIZE;
+
+       /* skip public */
+       val = tpm_buf_read_u16(buf, &offset);
+       if (val > tot_len)
+               return -EINVAL;
+       offset += val;
+       /* name */
+       val = tpm_buf_read_u16(buf, &offset);
+       if (val != name_size(&buf->data[offset]))
+               return -EINVAL;
+       memcpy(name, &buf->data[offset], val);
+       /* forget the rest */
+       return 0;
+}
+
+static int tpm2_read_public(struct tpm_chip *chip, u32 handle, char *name)
+{
+       struct tpm_buf buf;
+       int rc;
+
+       rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_READ_PUBLIC);
+       if (rc)
+               return rc;
+
+       tpm_buf_append_u32(&buf, handle);
+       rc = tpm_transmit_cmd(chip, &buf, 0, "read public");
+       if (rc == TPM2_RC_SUCCESS)
+               rc = tpm2_parse_read_public(name, &buf);
+
+       tpm_buf_destroy(&buf);
+
+       return rc;
+}
+
+/**
+ * tpm_buf_append_name() - add a handle area to the buffer
+ * @chip: the TPM chip structure
+ * @buf: The buffer to be appended
+ * @handle: The handle to be appended
+ * @name: The name of the handle (may be NULL)
+ *
+ * In order to compute session HMACs, we need to know the names of the
+ * objects pointed to by the handles.  For most objects, this is simply
+ * the actual 4 byte handle or an empty buf (in these cases @name
+ * should be NULL) but for volatile objects, permanent objects and NV
+ * areas, the name is defined as the hash (according to the name
+ * algorithm which should be set to sha256) of the public area to
+ * which the two byte algorithm id has been appended.  For these
+ * objects, the @name pointer should point to this.  If a name is
+ * required but @name is NULL, then TPM2_ReadPublic() will be called
+ * on the handle to obtain the name.
+ *
+ * As with most tpm_buf operations, success is assumed because failure
+ * will be caused by an incorrect programming model and indicated by a
+ * kernel message.
+ */
+void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
+                        u32 handle, u8 *name)
+{
+       enum tpm2_mso_type mso = tpm2_handle_mso(handle);
+       struct tpm2_auth *auth = chip->auth;
+       int slot;
+
+       slot = (tpm_buf_length(buf) - TPM_HEADER_SIZE)/4;
+       if (slot >= AUTH_MAX_NAMES) {
+               dev_err(&chip->dev, "TPM: too many handles\n");
+               return;
+       }
+       WARN(auth->session != tpm_buf_length(buf),
+            "name added in wrong place\n");
+       tpm_buf_append_u32(buf, handle);
+       auth->session += 4;
+
+       if (mso == TPM2_MSO_PERSISTENT ||
+           mso == TPM2_MSO_VOLATILE ||
+           mso == TPM2_MSO_NVRAM) {
+               if (!name)
+                       tpm2_read_public(chip, handle, auth->name[slot]);
+       } else {
+               if (name)
+                       dev_err(&chip->dev, "TPM: Handle does not require name but one is specified\n");
+       }
+
+       auth->name_h[slot] = handle;
+       if (name)
+               memcpy(auth->name[slot], name, name_size(name));
+}
+EXPORT_SYMBOL(tpm_buf_append_name);
+
+/**
+ * tpm_buf_check_hmac_response() - check the TPM return HMAC for correctness
+ * @chip: the TPM chip structure
+ * @buf: the original command buffer (which now contains the response)
+ * @rc: the return code from tpm_transmit_cmd
+ *
+ * If @rc is non zero, @buf may not contain an actual return, so @rc
+ * is passed through as the return and the session cleaned up and
+ * de-allocated if required (this is required if
+ * TPM2_SA_CONTINUE_SESSION was not specified as a session flag).
+ *
+ * If @rc is zero, the response HMAC is computed against the returned
+ * @buf and matched to the TPM one in the session area.  If there is a
+ * mismatch, an error is logged and -EINVAL returned.
+ *
+ * The reason for this is that the command issue and HMAC check
+ * sequence should look like:
+ *
+ *     rc = tpm_transmit_cmd(...);
+ *     rc = tpm_buf_check_hmac_response(&buf, auth, rc);
+ *     if (rc)
+ *             ...
+ *
+ * Which is easily layered into the current contrl flow.
+ *
+ * Returns: 0 on success or an error.
+ */
+int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
+                               int rc)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+       struct tpm2_auth *auth = chip->auth;
+       off_t offset_s, offset_p;
+       u8 rphash[SHA256_DIGEST_SIZE];
+       u32 attrs;
+       struct sha256_state sctx;
+       u16 tag = be16_to_cpu(head->tag);
+       u32 cc = be32_to_cpu(auth->ordinal);
+       int parm_len, len, i, handles;
+
+       if (auth->session >= TPM_HEADER_SIZE) {
+               WARN(1, "tpm session not filled correctly\n");
+               goto out;
+       }
+
+       if (rc != 0)
+               /* pass non success rc through and close the session */
+               goto out;
+
+       rc = -EINVAL;
+       if (tag != TPM2_ST_SESSIONS) {
+               dev_err(&chip->dev, "TPM: HMAC response check has no sessions tag\n");
+               goto out;
+       }
+
+       i = tpm2_find_cc(chip, cc);
+       if (i < 0)
+               goto out;
+       attrs = chip->cc_attrs_tbl[i];
+       handles = (attrs >> TPM2_CC_ATTR_RHANDLE) & 1;
+
+       /* point to area beyond handles */
+       offset_s = TPM_HEADER_SIZE + handles * 4;
+       parm_len = tpm_buf_read_u32(buf, &offset_s);
+       offset_p = offset_s;
+       offset_s += parm_len;
+       /* skip over any sessions before ours */
+       for (i = 0; i < auth->session - 1; i++) {
+               len = tpm_buf_read_u16(buf, &offset_s);
+               offset_s += len + 1;
+               len = tpm_buf_read_u16(buf, &offset_s);
+               offset_s += len;
+       }
+       /* TPM nonce */
+       len = tpm_buf_read_u16(buf, &offset_s);
+       if (offset_s + len > tpm_buf_length(buf))
+               goto out;
+       if (len != SHA256_DIGEST_SIZE)
+               goto out;
+       memcpy(auth->tpm_nonce, &buf->data[offset_s], len);
+       offset_s += len;
+       attrs = tpm_buf_read_u8(buf, &offset_s);
+       len = tpm_buf_read_u16(buf, &offset_s);
+       if (offset_s + len != tpm_buf_length(buf))
+               goto out;
+       if (len != SHA256_DIGEST_SIZE)
+               goto out;
+       /*
+        * offset_s points to the HMAC. now calculate comparison, beginning
+        * with rphash
+        */
+       sha256_init(&sctx);
+       /* yes, I know this is now zero, but it's what the standard says */
+       sha256_update(&sctx, (u8 *)&head->return_code,
+                     sizeof(head->return_code));
+       /* ordinal is already BE */
+       sha256_update(&sctx, (u8 *)&auth->ordinal, sizeof(auth->ordinal));
+       sha256_update(&sctx, &buf->data[offset_p], parm_len);
+       sha256_final(&sctx, rphash);
+
+       /* now calculate the hmac */
+       tpm2_hmac_init(&sctx, auth->session_key, sizeof(auth->session_key)
+                      + auth->passphrase_len);
+       sha256_update(&sctx, rphash, sizeof(rphash));
+       sha256_update(&sctx, auth->tpm_nonce, sizeof(auth->tpm_nonce));
+       sha256_update(&sctx, auth->our_nonce, sizeof(auth->our_nonce));
+       sha256_update(&sctx, &auth->attrs, 1);
+       /* we're done with the rphash, so put our idea of the hmac there */
+       tpm2_hmac_final(&sctx, auth->session_key, sizeof(auth->session_key)
+                       + auth->passphrase_len, rphash);
+       if (memcmp(rphash, &buf->data[offset_s], SHA256_DIGEST_SIZE) == 0) {
+               rc = 0;
+       } else {
+               dev_err(&chip->dev, "TPM: HMAC check failed\n");
+               goto out;
+       }
+
+       /* now do response decryption */
+       if (auth->attrs & TPM2_SA_ENCRYPT) {
+               /* need key and IV */
+               tpm2_KDFa(auth->session_key, SHA256_DIGEST_SIZE
+                         + auth->passphrase_len, "CFB", auth->tpm_nonce,
+                         auth->our_nonce, AES_KEY_BYTES + AES_BLOCK_SIZE,
+                         auth->scratch);
+
+               len = tpm_buf_read_u16(buf, &offset_p);
+               aes_expandkey(&auth->aes_ctx, auth->scratch, AES_KEY_BYTES);
+               aescfb_decrypt(&auth->aes_ctx, &buf->data[offset_p],
+                              &buf->data[offset_p], len,
+                              auth->scratch + AES_KEY_BYTES);
+       }
+
+ out:
+       if ((auth->attrs & TPM2_SA_CONTINUE_SESSION) == 0) {
+               if (rc)
+                       /* manually close the session if it wasn't consumed */
+                       tpm2_flush_context(chip, auth->handle);
+               memzero_explicit(auth, sizeof(*auth));
+       } else {
+               /* reset for next use  */
+               auth->session = TPM_HEADER_SIZE;
+       }
+
+       return rc;
+}
+EXPORT_SYMBOL(tpm_buf_check_hmac_response);
+
+/**
+ * tpm2_end_auth_session() - kill the allocated auth session
+ * @chip: the TPM chip structure
+ *
+ * ends the session started by tpm2_start_auth_session and frees all
+ * the resources.  Under normal conditions,
+ * tpm_buf_check_hmac_response() will correctly end the session if
+ * required, so this function is only for use in error legs that will
+ * bypass the normal invocation of tpm_buf_check_hmac_response().
+ */
+void tpm2_end_auth_session(struct tpm_chip *chip)
+{
+       tpm2_flush_context(chip, chip->auth->handle);
+       memzero_explicit(chip->auth, sizeof(*chip->auth));
+}
+EXPORT_SYMBOL(tpm2_end_auth_session);
+
+static int tpm2_parse_start_auth_session(struct tpm2_auth *auth,
+                                        struct tpm_buf *buf)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+       u32 tot_len = be32_to_cpu(head->length);
+       off_t offset = TPM_HEADER_SIZE;
+       u32 val;
+
+       /* we're starting after the header so adjust the length */
+       tot_len -= TPM_HEADER_SIZE;
+
+       /* should have handle plus nonce */
+       if (tot_len != 4 + 2 + sizeof(auth->tpm_nonce))
+               return -EINVAL;
+
+       auth->handle = tpm_buf_read_u32(buf, &offset);
+       val = tpm_buf_read_u16(buf, &offset);
+       if (val != sizeof(auth->tpm_nonce))
+               return -EINVAL;
+       memcpy(auth->tpm_nonce, &buf->data[offset], sizeof(auth->tpm_nonce));
+       /* now compute the session key from the nonces */
+       tpm2_KDFa(auth->salt, sizeof(auth->salt), "ATH", auth->tpm_nonce,
+                 auth->our_nonce, sizeof(auth->session_key),
+                 auth->session_key);
+
+       return 0;
+}
+
+static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key)
+{
+       int rc;
+       unsigned int offset = 0; /* dummy offset for null seed context */
+       u8 name[SHA256_DIGEST_SIZE + 2];
+
+       rc = tpm2_load_context(chip, chip->null_key_context, &offset,
+                              null_key);
+       if (rc != -EINVAL)
+               return rc;
+
+       /* an integrity failure may mean the TPM has been reset */
+       dev_err(&chip->dev, "NULL key integrity failure!\n");
+       /* check the null name against what we know */
+       tpm2_create_primary(chip, TPM2_RH_NULL, NULL, name);
+       if (memcmp(name, chip->null_key_name, sizeof(name)) == 0)
+               /* name unchanged, assume transient integrity failure */
+               return rc;
+       /*
+        * Fatal TPM failure: the NULL seed has actually changed, so
+        * the TPM must have been illegally reset.  All in-kernel TPM
+        * operations will fail because the NULL primary can't be
+        * loaded to salt the sessions, but disable the TPM anyway so
+        * userspace programmes can't be compromised by it.
+        */
+       dev_err(&chip->dev, "NULL name has changed, disabling TPM due to interference\n");
+       chip->flags |= TPM_CHIP_FLAG_DISABLE;
+
+       return rc;
+}
+
+/**
+ * tpm2_start_auth_session() - create a HMAC authentication session with the TPM
+ * @chip: the TPM chip structure to create the session with
+ *
+ * This function loads the NULL seed from its saved context and starts
+ * an authentication session on the null seed, fills in the
+ * @chip->auth structure to contain all the session details necessary
+ * for performing the HMAC, encrypt and decrypt operations and
+ * returns.  The NULL seed is flushed before this function returns.
+ *
+ * Return: zero on success or actual error encountered.
+ */
+int tpm2_start_auth_session(struct tpm_chip *chip)
+{
+       struct tpm_buf buf;
+       struct tpm2_auth *auth = chip->auth;
+       int rc;
+       u32 null_key;
+
+       rc = tpm2_load_null(chip, &null_key);
+       if (rc)
+               goto out;
+
+       auth->session = TPM_HEADER_SIZE;
+
+       rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_START_AUTH_SESS);
+       if (rc)
+               goto out;
+
+       /* salt key handle */
+       tpm_buf_append_u32(&buf, null_key);
+       /* bind key handle */
+       tpm_buf_append_u32(&buf, TPM2_RH_NULL);
+       /* nonce caller */
+       get_random_bytes(auth->our_nonce, sizeof(auth->our_nonce));
+       tpm_buf_append_u16(&buf, sizeof(auth->our_nonce));
+       tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce));
+
+       /* append encrypted salt and squirrel away unencrypted in auth */
+       tpm_buf_append_salt(&buf, chip);
+       /* session type (HMAC, audit or policy) */
+       tpm_buf_append_u8(&buf, TPM2_SE_HMAC);
+
+       /* symmetric encryption parameters */
+       /* symmetric algorithm */
+       tpm_buf_append_u16(&buf, TPM_ALG_AES);
+       /* bits for symmetric algorithm */
+       tpm_buf_append_u16(&buf, AES_KEY_BITS);
+       /* symmetric algorithm mode (must be CFB) */
+       tpm_buf_append_u16(&buf, TPM_ALG_CFB);
+       /* hash algorithm for session */
+       tpm_buf_append_u16(&buf, TPM_ALG_SHA256);
+
+       rc = tpm_transmit_cmd(chip, &buf, 0, "start auth session");
+       tpm2_flush_context(chip, null_key);
+
+       if (rc == TPM2_RC_SUCCESS)
+               rc = tpm2_parse_start_auth_session(auth, &buf);
+
+       tpm_buf_destroy(&buf);
+
+       if (rc)
+               goto out;
+
+ out:
+       return rc;
+}
+EXPORT_SYMBOL(tpm2_start_auth_session);
+
+/**
+ * tpm2_parse_create_primary() - parse the data returned from TPM_CC_CREATE_PRIMARY
+ *
+ * @chip:      The TPM the primary was created under
+ * @buf:       The response buffer from the chip
+ * @handle:    pointer to be filled in with the return handle of the primary
+ * @hierarchy: The hierarchy the primary was created for
+ * @name:      pointer to be filled in with the primary key name
+ *
+ * Return:
+ * * 0         - OK
+ * * -errno    - A system error
+ * * TPM_RC    - A TPM error
+ */
+static int tpm2_parse_create_primary(struct tpm_chip *chip, struct tpm_buf *buf,
+                                    u32 *handle, u32 hierarchy, u8 *name)
+{
+       struct tpm_header *head = (struct tpm_header *)buf->data;
+       off_t offset_r = TPM_HEADER_SIZE, offset_t;
+       u16 len = TPM_HEADER_SIZE;
+       u32 total_len = be32_to_cpu(head->length);
+       u32 val, param_len, keyhandle;
+
+       keyhandle = tpm_buf_read_u32(buf, &offset_r);
+       if (handle)
+               *handle = keyhandle;
+       else
+               tpm2_flush_context(chip, keyhandle);
+
+       param_len = tpm_buf_read_u32(buf, &offset_r);
+       /*
+        * param_len doesn't include the header, but all the other
+        * lengths and offsets do, so add it to parm len to make
+        * the comparisons easier
+        */
+       param_len += TPM_HEADER_SIZE;
+
+       if (param_len + 8 > total_len)
+               return -EINVAL;
+       len = tpm_buf_read_u16(buf, &offset_r);
+       offset_t = offset_r;
+       if (name) {
+               /*
+                * now we have the public area, compute the name of
+                * the object
+                */
+               put_unaligned_be16(TPM_ALG_SHA256, name);
+               sha256(&buf->data[offset_r], len, name + 2);
+       }
+
+       /* validate the public key */
+       val = tpm_buf_read_u16(buf, &offset_t);
+
+       /* key type (must be what we asked for) */
+       if (val != TPM_ALG_ECC)
+               return -EINVAL;
+       val = tpm_buf_read_u16(buf, &offset_t);
+
+       /* name algorithm */
+       if (val != TPM_ALG_SHA256)
+               return -EINVAL;
+       val = tpm_buf_read_u32(buf, &offset_t);
+
+       /* object properties */
+       if (val != TPM2_OA_TMPL)
+               return -EINVAL;
+
+       /* auth policy (empty) */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != 0)
+               return -EINVAL;
+
+       /* symmetric key parameters */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != TPM_ALG_AES)
+               return -EINVAL;
+
+       /* symmetric key length */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != AES_KEY_BITS)
+               return -EINVAL;
+
+       /* symmetric encryption scheme */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != TPM_ALG_CFB)
+               return -EINVAL;
+
+       /* signing scheme */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != TPM_ALG_NULL)
+               return -EINVAL;
+
+       /* ECC Curve */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != TPM2_ECC_NIST_P256)
+               return -EINVAL;
+
+       /* KDF Scheme */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != TPM_ALG_NULL)
+               return -EINVAL;
+
+       /* extract public key (x and y points) */
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != EC_PT_SZ)
+               return -EINVAL;
+       memcpy(chip->null_ec_key_x, &buf->data[offset_t], val);
+       offset_t += val;
+       val = tpm_buf_read_u16(buf, &offset_t);
+       if (val != EC_PT_SZ)
+               return -EINVAL;
+       memcpy(chip->null_ec_key_y, &buf->data[offset_t], val);
+       offset_t += val;
+
+       /* original length of the whole TPM2B */
+       offset_r += len;
+
+       /* should have exactly consumed the TPM2B public structure */
+       if (offset_t != offset_r)
+               return -EINVAL;
+       if (offset_r > param_len)
+               return -EINVAL;
+
+       /* creation data (skip) */
+       len = tpm_buf_read_u16(buf, &offset_r);
+       offset_r += len;
+       if (offset_r > param_len)
+               return -EINVAL;
+
+       /* creation digest (must be sha256) */
+       len = tpm_buf_read_u16(buf, &offset_r);
+       offset_r += len;
+       if (len != SHA256_DIGEST_SIZE || offset_r > param_len)
+               return -EINVAL;
+
+       /* TPMT_TK_CREATION follows */
+       /* tag, must be TPM_ST_CREATION (0x8021) */
+       val = tpm_buf_read_u16(buf, &offset_r);
+       if (val != TPM2_ST_CREATION || offset_r > param_len)
+               return -EINVAL;
+
+       /* hierarchy */
+       val = tpm_buf_read_u32(buf, &offset_r);
+       if (val != hierarchy || offset_r > param_len)
+               return -EINVAL;
+
+       /* the ticket digest HMAC (might not be sha256) */
+       len = tpm_buf_read_u16(buf, &offset_r);
+       offset_r += len;
+       if (offset_r > param_len)
+               return -EINVAL;
+
+       /*
+        * finally we have the name, which is a sha256 digest plus a 2
+        * byte algorithm type
+        */
+       len = tpm_buf_read_u16(buf, &offset_r);
+       if (offset_r + len != param_len + 8)
+               return -EINVAL;
+       if (len != SHA256_DIGEST_SIZE + 2)
+               return -EINVAL;
+
+       if (memcmp(chip->null_key_name, &buf->data[offset_r],
+                  SHA256_DIGEST_SIZE + 2) != 0) {
+               dev_err(&chip->dev, "NULL Seed name comparison failed\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/**
+ * tpm2_create_primary() - create a primary key using a fixed P-256 template
+ *
+ * @chip:      the TPM chip to create under
+ * @hierarchy: The hierarchy handle to create under
+ * @handle:    The returned volatile handle on success
+ * @name:      The name of the returned key
+ *
+ * For platforms that might not have a persistent primary, this can be
+ * used to create one quickly on the fly (it uses Elliptic Curve not
+ * RSA, so even slow TPMs can create one fast).  The template uses the
+ * TCG mandated H one for non-endorsement ECC primaries, i.e. P-256
+ * elliptic curve (the only current one all TPM2s are required to
+ * have) a sha256 name hash and no policy.
+ *
+ * Return:
+ * * 0         - OK
+ * * -errno    - A system error
+ * * TPM_RC    - A TPM error
+ */
+static int tpm2_create_primary(struct tpm_chip *chip, u32 hierarchy,
+                              u32 *handle, u8 *name)
+{
+       int rc;
+       struct tpm_buf buf;
+       struct tpm_buf template;
+
+       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE_PRIMARY);
+       if (rc)
+               return rc;
+
+       rc = tpm_buf_init_sized(&template);
+       if (rc) {
+               tpm_buf_destroy(&buf);
+               return rc;
+       }
+
+       /*
+        * create the template.  Note: in order for userspace to
+        * verify the security of the system, it will have to create
+        * and certify this NULL primary, meaning all the template
+        * parameters will have to be identical, so conform exactly to
+        * the TCG TPM v2.0 Provisioning Guidance for the SRK ECC
+        * key H template (H has zero size unique points)
+        */
+
+       /* key type */
+       tpm_buf_append_u16(&template, TPM_ALG_ECC);
+
+       /* name algorithm */
+       tpm_buf_append_u16(&template, TPM_ALG_SHA256);
+
+       /* object properties */
+       tpm_buf_append_u32(&template, TPM2_OA_TMPL);
+
+       /* sauth policy (empty) */
+       tpm_buf_append_u16(&template, 0);
+
+       /* BEGIN parameters: key specific; for ECC*/
+
+       /* symmetric algorithm */
+       tpm_buf_append_u16(&template, TPM_ALG_AES);
+
+       /* bits for symmetric algorithm */
+       tpm_buf_append_u16(&template, AES_KEY_BITS);
+
+       /* algorithm mode (must be CFB) */
+       tpm_buf_append_u16(&template, TPM_ALG_CFB);
+
+       /* scheme (NULL means any scheme) */
+       tpm_buf_append_u16(&template, TPM_ALG_NULL);
+
+       /* ECC Curve ID */
+       tpm_buf_append_u16(&template, TPM2_ECC_NIST_P256);
+
+       /* KDF Scheme */
+       tpm_buf_append_u16(&template, TPM_ALG_NULL);
+
+       /* unique: key specific; for ECC it is two zero size points */
+       tpm_buf_append_u16(&template, 0);
+       tpm_buf_append_u16(&template, 0);
+
+       /* END parameters */
+
+       /* primary handle */
+       tpm_buf_append_u32(&buf, hierarchy);
+       tpm_buf_append_empty_auth(&buf, TPM2_RS_PW);
+
+       /* sensitive create size is 4 for two empty buffers */
+       tpm_buf_append_u16(&buf, 4);
+
+       /* sensitive create auth data (empty) */
+       tpm_buf_append_u16(&buf, 0);
+
+       /* sensitive create sensitive data (empty) */
+       tpm_buf_append_u16(&buf, 0);
+
+       /* the public template */
+       tpm_buf_append(&buf, template.data, template.length);
+       tpm_buf_destroy(&template);
+
+       /* outside info (empty) */
+       tpm_buf_append_u16(&buf, 0);
+
+       /* creation PCR (none) */
+       tpm_buf_append_u32(&buf, 0);
+
+       rc = tpm_transmit_cmd(chip, &buf, 0,
+                             "attempting to create NULL primary");
+
+       if (rc == TPM2_RC_SUCCESS)
+               rc = tpm2_parse_create_primary(chip, &buf, handle, hierarchy,
+                                              name);
+
+       tpm_buf_destroy(&buf);
+
+       return rc;
+}
+
+static int tpm2_create_null_primary(struct tpm_chip *chip)
+{
+       u32 null_key;
+       int rc;
+
+       rc = tpm2_create_primary(chip, TPM2_RH_NULL, &null_key,
+                                chip->null_key_name);
+
+       if (rc == TPM2_RC_SUCCESS) {
+               unsigned int offset = 0; /* dummy offset for null key context */
+
+               rc = tpm2_save_context(chip, null_key, chip->null_key_context,
+                                      sizeof(chip->null_key_context), &offset);
+               tpm2_flush_context(chip, null_key);
+       }
+
+       return rc;
+}
+
+/**
+ * tpm2_sessions_init() - start of day initialization for the sessions code
+ * @chip: TPM chip
+ *
+ * Derive and context save the null primary and allocate memory in the
+ * struct tpm_chip for the authorizations.
+ */
+int tpm2_sessions_init(struct tpm_chip *chip)
+{
+       int rc;
+
+       rc = tpm2_create_null_primary(chip);
+       if (rc)
+               dev_err(&chip->dev, "TPM: security failed (NULL seed derivation): %d\n", rc);
+
+       chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL);
+       if (!chip->auth)
+               return -ENOMEM;
+
+       return rc;
+}
index 363afdd4d1d30635e2e2e07d8cd136870dc82889..4892d491da8dae1aace910e0f2ff75136097a1d5 100644 (file)
@@ -68,8 +68,8 @@ void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
        kfree(space->session_buf);
 }
 
-static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
-                            unsigned int *offset, u32 *handle)
+int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
+                     unsigned int *offset, u32 *handle)
 {
        struct tpm_buf tbuf;
        struct tpm2_context *ctx;
@@ -105,6 +105,9 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
                *handle = 0;
                tpm_buf_destroy(&tbuf);
                return -ENOENT;
+       } else if (tpm2_rc_value(rc) == TPM2_RC_INTEGRITY) {
+               tpm_buf_destroy(&tbuf);
+               return -EINVAL;
        } else if (rc > 0) {
                dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
                         __func__, rc);
@@ -119,8 +122,8 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
        return 0;
 }
 
-static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
-                            unsigned int buf_size, unsigned int *offset)
+int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
+                     unsigned int buf_size, unsigned int *offset)
 {
        struct tpm_buf tbuf;
        unsigned int body_size;
index 9c924a1440a913deb1dd46ad21414d0032b683dc..2d2ae37153ba00c3a1eacde3cf3daf8c76d4522a 100644 (file)
@@ -51,34 +51,40 @@ static struct tpm_inf_dev tpm_dev;
 
 static inline void tpm_data_out(unsigned char data, unsigned char offset)
 {
+#ifdef CONFIG_HAS_IOPORT
        if (tpm_dev.iotype == TPM_INF_IO_PORT)
                outb(data, tpm_dev.data_regs + offset);
        else
+#endif
                writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
 }
 
 static inline unsigned char tpm_data_in(unsigned char offset)
 {
+#ifdef CONFIG_HAS_IOPORT
        if (tpm_dev.iotype == TPM_INF_IO_PORT)
                return inb(tpm_dev.data_regs + offset);
-       else
-               return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
+#endif
+       return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
 }
 
 static inline void tpm_config_out(unsigned char data, unsigned char offset)
 {
+#ifdef CONFIG_HAS_IOPORT
        if (tpm_dev.iotype == TPM_INF_IO_PORT)
                outb(data, tpm_dev.config_port + offset);
        else
+#endif
                writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
 }
 
 static inline unsigned char tpm_config_in(unsigned char offset)
 {
+#ifdef CONFIG_HAS_IOPORT
        if (tpm_dev.iotype == TPM_INF_IO_PORT)
                return inb(tpm_dev.config_port + offset);
-       else
-               return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
+#endif
+       return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
 }
 
 /* TPM header definitions */
index 714070ebb6e7a21d957fc4cff3920e12984c71af..176cd8dbf1db2c61d5f2ed193c63822e898ac9c6 100644 (file)
@@ -1057,11 +1057,6 @@ static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value)
                clkrun_val &= ~LPC_CLKRUN_EN;
                iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
 
-               /*
-                * Write any random value on port 0x80 which is on LPC, to make
-                * sure LPC clock is running before sending any TPM command.
-                */
-               outb(0xCC, 0x80);
        } else {
                data->clkrun_enabled--;
                if (data->clkrun_enabled)
@@ -1072,13 +1067,15 @@ static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value)
                /* Enable LPC CLKRUN# */
                clkrun_val |= LPC_CLKRUN_EN;
                iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
-
-               /*
-                * Write any random value on port 0x80 which is on LPC, to make
-                * sure LPC clock is running before sending any TPM command.
-                */
-               outb(0xCC, 0x80);
        }
+
+#ifdef CONFIG_HAS_IOPORT
+       /*
+        * Write any random value on port 0x80 which is on LPC, to make
+        * sure LPC clock is running before sending any TPM command.
+        */
+       outb(0xCC, 0x80);
+#endif
 }
 
 static const struct tpm_class_ops tpm_tis = {
index 50af5fc7f5708035baa797ebdf1afcdcc1bcbde8..7517a0dfd15c2a8a4cd08e06c17b67cf6858c7ec 100644 (file)
@@ -451,8 +451,8 @@ config COMMON_CLK_FIXED_MMIO
 
 config COMMON_CLK_K210
        bool "Clock driver for the Canaan Kendryte K210 SoC"
-       depends on OF && RISCV && SOC_CANAAN
-       default SOC_CANAAN
+       depends on OF && RISCV && SOC_CANAAN_K210
+       default SOC_CANAAN_K210
        help
          Support for the Canaan Kendryte K210 RISC-V SoC clocks.
 
index 8602c02047d0481b28e7c7da75ddb1564aa3da14..45c5255bcd11bae69b83138ba1d5e52a8a3f3be8 100644 (file)
@@ -768,6 +768,7 @@ static struct clk_smd_rpm *msm8976_clks[] = {
 
 static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
        .clks = msm8976_clks,
+       .num_clks = ARRAY_SIZE(msm8976_clks),
        .icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
        .num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
 };
index e7a4068b9f3906f99d9d5ca444fe903b237811b6..df9618ab7eea1fb0422ee73fd21938e6fc77e257 100644 (file)
@@ -487,9 +487,14 @@ int gdsc_register(struct gdsc_desc *desc,
                if (!scs[i] || !scs[i]->supply)
                        continue;
 
-               scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
-               if (IS_ERR(scs[i]->rsupply))
-                       return PTR_ERR(scs[i]->rsupply);
+               scs[i]->rsupply = devm_regulator_get_optional(dev, scs[i]->supply);
+               if (IS_ERR(scs[i]->rsupply)) {
+                       ret = PTR_ERR(scs[i]->rsupply);
+                       if (ret != -ENODEV)
+                               return ret;
+
+                       scs[i]->rsupply = NULL;
+               }
        }
 
        data->num_domains = num;
index 3484e6cc80ad10d1eceaba017de2a9bfc7602880..503c6f5b20d5c5538dc2bfc44afbc594df0878d6 100644 (file)
@@ -13,9 +13,9 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
-#include <linux/property.h>
 
 #define EXYNOS_CLKOUT_NR_CLKS          1
 #define EXYNOS_CLKOUT_PARENTS          32
@@ -84,17 +84,24 @@ MODULE_DEVICE_TABLE(of, exynos_clkout_ids);
 static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
 {
        const struct exynos_clkout_variant *variant;
+       const struct of_device_id *match;
 
        if (!dev->parent) {
                dev_err(dev, "not instantiated from MFD\n");
                return -EINVAL;
        }
 
-       variant = device_get_match_data(dev->parent);
-       if (!variant) {
+       /*
+        * 'exynos_clkout_ids' arrays is not the ids array matched by
+        * the dev->parent driver, so of_device_get_match_data() or
+        * device_get_match_data() cannot be used here.
+        */
+       match = of_match_device(exynos_clkout_ids, dev->parent);
+       if (!match) {
                dev_err(dev, "cannot match parent device\n");
                return -EINVAL;
        }
+       variant = match->data;
 
        *mux_mask = variant->mux_mask;
 
index 8951ffc14ff52c5a2bd7d6be60f47539cad36fb1..6a4b2b9ef30a82e1721e21695f299351a378f8fb 100644 (file)
@@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
                                              &ccu_nkm_ops,
                                              CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
                .features       = CCU_FEATURE_CLOSEST_RATE,
+               .min_rate       = 500000000,
+               .max_rate       = 1400000000,
        },
 };
 
index 42568c6161814dc797079d1ee224bc7a2e6847a8..892df807275c8e57b1b53112faece02a47f22f6e 100644 (file)
@@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
        SUN50I_H6_USB3_CLK_REG,
 };
 
+static struct ccu_mux_nb sun50i_h6_cpu_nb = {
+       .common         = &cpux_clk.common,
+       .cm             = &cpux_clk.mux,
+       .delay_us       = 1,
+       .bypass_index   = 0, /* index of 24 MHz oscillator */
+};
+
 static int sun50i_h6_ccu_probe(struct platform_device *pdev)
 {
        void __iomem *reg;
+       int i, ret;
        u32 val;
-       int i;
 
        reg = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(reg))
@@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
        val |= BIT(24);
        writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
 
-       return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
+       ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
+       if (ret)
+               return ret;
+
+       /* Reparent CPU during PLL CPUX rate changes */
+       ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+                                 &sun50i_h6_cpu_nb);
+
+       return 0;
 }
 
 static const struct of_device_id sun50i_h6_ccu_ids[] = {
index 8babce55302f5f9dd9ddd59ef0113e3af5171d37..ac0091b4ce2425b77750619383531191c228e7ed 100644 (file)
@@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
                        unsigned long current_rate,
                        unsigned long best_rate)
 {
+       unsigned long min_rate, max_rate;
+
+       clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);
+
+       if (current_rate > max_rate)
+               return false;
+
+       if (current_rate < min_rate)
+               return false;
+
        if (common->features & CCU_FEATURE_CLOSEST_RATE)
                return abs(current_rate - target_rate) < abs(best_rate - target_rate);
 
@@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
 
        for (i = 0; i < desc->hw_clks->num ; i++) {
                struct clk_hw *hw = desc->hw_clks->hws[i];
+               struct ccu_common *common = hw_to_ccu_common(hw);
                const char *name;
 
                if (!hw)
@@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
                        pr_err("Couldn't register clock %d - %s\n", i, name);
                        goto err_clk_unreg;
                }
+
+               if (common->max_rate)
+                       clk_hw_set_rate_range(hw, common->min_rate,
+                                             common->max_rate);
+               else
+                       WARN(common->min_rate,
+                            "No max_rate, ignoring min_rate of clock %d - %s\n",
+                            i, name);
        }
 
        ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
index 942a72c094374435d73e9f27ddfd04af4f241fd4..329734f8cf42b41263fbc4eb2de9bb1315e498e1 100644 (file)
@@ -31,6 +31,9 @@ struct ccu_common {
        u16             lock_reg;
        u32             prediv;
 
+       unsigned long   min_rate;
+       unsigned long   max_rate;
+
        unsigned long   features;
        spinlock_t      *lock;
        struct clk_hw   hw;
index 3d02702456a507606572e9fd84ce226d87e3ad9b..bfe18ebc2a981bfef3a5225ed5c40f7578e580b0 100644 (file)
@@ -67,6 +67,7 @@ config CRYPTO_DEV_GEODE
 config ZCRYPT
        tristate "Support for s390 cryptographic adapters"
        depends on S390
+       depends on AP
        select HW_RANDOM
        help
          Select this option if you want to enable support for
@@ -74,23 +75,6 @@ config ZCRYPT
          to 8 in Coprocessor (CEXxC), EP11 Coprocessor (CEXxP)
          or Accelerator (CEXxA) mode.
 
-config ZCRYPT_DEBUG
-       bool "Enable debug features for s390 cryptographic adapters"
-       default n
-       depends on DEBUG_KERNEL
-       depends on ZCRYPT
-       help
-         Say 'Y' here to enable some additional debug features on the
-         s390 cryptographic adapters driver.
-
-         There will be some more sysfs attributes displayed for ap cards
-         and queues and some flags on crypto requests are interpreted as
-         debugging messages to force error injection.
-
-         Do not enable on production level kernel build.
-
-         If unsure, say N.
-
 config PKEY
        tristate "Kernel API for protected key handling"
        depends on S390
index 2b3ebe0db3a6d9204e30eb58056404aaa2de2e5f..057d73c370b735870125d918126577ed200bf208 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/stmp_device.h>
 #include <linux/clk.h>
+#include <soc/fsl/dcp.h>
 
 #include <crypto/aes.h>
 #include <crypto/sha1.h>
@@ -101,6 +102,7 @@ struct dcp_async_ctx {
        struct crypto_skcipher          *fallback;
        unsigned int                    key_len;
        uint8_t                         key[AES_KEYSIZE_128];
+       bool                            key_referenced;
 };
 
 struct dcp_aes_req_ctx {
@@ -155,6 +157,7 @@ static struct dcp *global_sdcp;
 #define MXS_DCP_CONTROL0_HASH_TERM             (1 << 13)
 #define MXS_DCP_CONTROL0_HASH_INIT             (1 << 12)
 #define MXS_DCP_CONTROL0_PAYLOAD_KEY           (1 << 11)
+#define MXS_DCP_CONTROL0_OTP_KEY               (1 << 10)
 #define MXS_DCP_CONTROL0_CIPHER_ENCRYPT                (1 << 8)
 #define MXS_DCP_CONTROL0_CIPHER_INIT           (1 << 9)
 #define MXS_DCP_CONTROL0_ENABLE_HASH           (1 << 6)
@@ -168,6 +171,8 @@ static struct dcp *global_sdcp;
 #define MXS_DCP_CONTROL1_CIPHER_MODE_ECB       (0 << 4)
 #define MXS_DCP_CONTROL1_CIPHER_SELECT_AES128  (0 << 0)
 
+#define MXS_DCP_CONTROL1_KEY_SELECT_SHIFT      8
+
 static int mxs_dcp_start_dma(struct dcp_async_ctx *actx)
 {
        int dma_err;
@@ -224,13 +229,16 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
        struct dcp *sdcp = global_sdcp;
        struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan];
        struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req);
+       bool key_referenced = actx->key_referenced;
        int ret;
 
-       key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key,
-                                 2 * AES_KEYSIZE_128, DMA_TO_DEVICE);
-       ret = dma_mapping_error(sdcp->dev, key_phys);
-       if (ret)
-               return ret;
+       if (!key_referenced) {
+               key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key,
+                                         2 * AES_KEYSIZE_128, DMA_TO_DEVICE);
+               ret = dma_mapping_error(sdcp->dev, key_phys);
+               if (ret)
+                       return ret;
+       }
 
        src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf,
                                  DCP_BUF_SZ, DMA_TO_DEVICE);
@@ -255,8 +263,12 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
                    MXS_DCP_CONTROL0_INTERRUPT |
                    MXS_DCP_CONTROL0_ENABLE_CIPHER;
 
-       /* Payload contains the key. */
-       desc->control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY;
+       if (key_referenced)
+               /* Set OTP key bit to select the key via KEY_SELECT. */
+               desc->control0 |= MXS_DCP_CONTROL0_OTP_KEY;
+       else
+               /* Payload contains the key. */
+               desc->control0 |= MXS_DCP_CONTROL0_PAYLOAD_KEY;
 
        if (rctx->enc)
                desc->control0 |= MXS_DCP_CONTROL0_CIPHER_ENCRYPT;
@@ -270,6 +282,9 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
        else
                desc->control1 |= MXS_DCP_CONTROL1_CIPHER_MODE_CBC;
 
+       if (key_referenced)
+               desc->control1 |= sdcp->coh->aes_key[0] << MXS_DCP_CONTROL1_KEY_SELECT_SHIFT;
+
        desc->next_cmd_addr = 0;
        desc->source = src_phys;
        desc->destination = dst_phys;
@@ -284,9 +299,9 @@ aes_done_run:
 err_dst:
        dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE);
 err_src:
-       dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128,
-                        DMA_TO_DEVICE);
-
+       if (!key_referenced)
+               dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128,
+                                DMA_TO_DEVICE);
        return ret;
 }
 
@@ -453,7 +468,7 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb)
        struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req);
        int ret;
 
-       if (unlikely(actx->key_len != AES_KEYSIZE_128))
+       if (unlikely(actx->key_len != AES_KEYSIZE_128 && !actx->key_referenced))
                return mxs_dcp_block_fallback(req, enc);
 
        rctx->enc = enc;
@@ -500,6 +515,7 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
         * there can still be an operation in progress.
         */
        actx->key_len = len;
+       actx->key_referenced = false;
        if (len == AES_KEYSIZE_128) {
                memcpy(actx->key, key, len);
                return 0;
@@ -516,6 +532,32 @@ static int mxs_dcp_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
        return crypto_skcipher_setkey(actx->fallback, key, len);
 }
 
+static int mxs_dcp_aes_setrefkey(struct crypto_skcipher *tfm, const u8 *key,
+                                unsigned int len)
+{
+       struct dcp_async_ctx *actx = crypto_skcipher_ctx(tfm);
+
+       if (len != DCP_PAES_KEYSIZE)
+               return -EINVAL;
+
+       switch (key[0]) {
+       case DCP_PAES_KEY_SLOT0:
+       case DCP_PAES_KEY_SLOT1:
+       case DCP_PAES_KEY_SLOT2:
+       case DCP_PAES_KEY_SLOT3:
+       case DCP_PAES_KEY_UNIQUE:
+       case DCP_PAES_KEY_OTP:
+               memcpy(actx->key, key, len);
+               actx->key_len = len;
+               actx->key_referenced = true;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int mxs_dcp_aes_fallback_init_tfm(struct crypto_skcipher *tfm)
 {
        const char *name = crypto_tfm_alg_name(crypto_skcipher_tfm(tfm));
@@ -539,6 +581,13 @@ static void mxs_dcp_aes_fallback_exit_tfm(struct crypto_skcipher *tfm)
        crypto_free_skcipher(actx->fallback);
 }
 
+static int mxs_dcp_paes_init_tfm(struct crypto_skcipher *tfm)
+{
+       crypto_skcipher_set_reqsize(tfm, sizeof(struct dcp_aes_req_ctx));
+
+       return 0;
+}
+
 /*
  * Hashing (SHA1/SHA256)
  */
@@ -889,6 +938,39 @@ static struct skcipher_alg dcp_aes_algs[] = {
                .ivsize                 = AES_BLOCK_SIZE,
                .init                   = mxs_dcp_aes_fallback_init_tfm,
                .exit                   = mxs_dcp_aes_fallback_exit_tfm,
+       }, {
+               .base.cra_name          = "ecb(paes)",
+               .base.cra_driver_name   = "ecb-paes-dcp",
+               .base.cra_priority      = 401,
+               .base.cra_alignmask     = 15,
+               .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL,
+               .base.cra_blocksize     = AES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct dcp_async_ctx),
+               .base.cra_module        = THIS_MODULE,
+
+               .min_keysize            = DCP_PAES_KEYSIZE,
+               .max_keysize            = DCP_PAES_KEYSIZE,
+               .setkey                 = mxs_dcp_aes_setrefkey,
+               .encrypt                = mxs_dcp_aes_ecb_encrypt,
+               .decrypt                = mxs_dcp_aes_ecb_decrypt,
+               .init                   = mxs_dcp_paes_init_tfm,
+       }, {
+               .base.cra_name          = "cbc(paes)",
+               .base.cra_driver_name   = "cbc-paes-dcp",
+               .base.cra_priority      = 401,
+               .base.cra_alignmask     = 15,
+               .base.cra_flags         = CRYPTO_ALG_ASYNC | CRYPTO_ALG_INTERNAL,
+               .base.cra_blocksize     = AES_BLOCK_SIZE,
+               .base.cra_ctxsize       = sizeof(struct dcp_async_ctx),
+               .base.cra_module        = THIS_MODULE,
+
+               .min_keysize            = DCP_PAES_KEYSIZE,
+               .max_keysize            = DCP_PAES_KEYSIZE,
+               .setkey                 = mxs_dcp_aes_setrefkey,
+               .encrypt                = mxs_dcp_aes_cbc_encrypt,
+               .decrypt                = mxs_dcp_aes_cbc_decrypt,
+               .ivsize                 = AES_BLOCK_SIZE,
+               .init                   = mxs_dcp_paes_init_tfm,
        },
 };
 
index 762783bb091afc8a40883c9ab2ee9c0f39e37219..887ed6e358fb9f6c77fcb9ba9424342df4e03579 100644 (file)
@@ -2184,6 +2184,7 @@ static bool parent_port_is_cxl_root(struct cxl_port *port)
 int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
                                      struct access_coordinate *coord)
 {
+       struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
        struct access_coordinate c[] = {
                {
                        .read_bandwidth = UINT_MAX,
@@ -2197,12 +2198,20 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
        struct cxl_port *iter = port;
        struct cxl_dport *dport;
        struct pci_dev *pdev;
+       struct device *dev;
        unsigned int bw;
        bool is_cxl_root;
 
        if (!is_cxl_endpoint(port))
                return -EINVAL;
 
+       /*
+        * Skip calculation for RCD. Expectation is HMAT already covers RCD case
+        * since RCH does not support hotplug.
+        */
+       if (cxlmd->cxlds->rcd)
+               return 0;
+
        /*
         * Exit the loop when the parent port of the current iter port is cxl
         * root. The iterative loop starts at the endpoint and gathers the
@@ -2232,8 +2241,12 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
                return -EINVAL;
        cxl_coordinates_combine(c, c, dport->coord);
 
+       dev = port->uport_dev->parent;
+       if (!dev_is_pci(dev))
+               return -ENODEV;
+
        /* Get the calculated PCI paths bandwidth */
-       pdev = to_pci_dev(port->uport_dev->parent);
+       pdev = to_pci_dev(dev);
        bw = pcie_bandwidth_available(pdev, NULL, NULL, NULL);
        if (bw == 0)
                return -ENXIO;
index 93ebedc5ec8ca36357635e774d5ca094d0e70e54..c24ef4d3cf3104f73d390ecaa4f490695a68b418 100644 (file)
@@ -377,7 +377,7 @@ static const struct file_operations dax_fops = {
        .release = dax_release,
        .get_unmapped_area = dax_get_unmapped_area,
        .mmap = dax_mmap,
-       .mmap_supported_flags = MAP_SYNC,
+       .fop_flags = FOP_MMAP_SYNC,
 };
 
 static void dev_dax_cdev_del(void *cdev)
index 5527055b09641c6f36ec4889b235435b7a7fcac0..ea7a9a342dd30b56ea39ebb5505c303c6be3176b 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/edac.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
 
@@ -299,6 +300,7 @@ struct synps_ecc_status {
 /**
  * struct synps_edac_priv - DDR memory controller private instance data.
  * @baseaddr:          Base address of the DDR controller.
+ * @reglock:           Concurrent CSRs access lock.
  * @message:           Buffer for framing the event specific info.
  * @stat:              ECC status information.
  * @p_data:            Platform data.
@@ -313,6 +315,7 @@ struct synps_ecc_status {
  */
 struct synps_edac_priv {
        void __iomem *baseaddr;
+       spinlock_t reglock;
        char message[SYNPS_EDAC_MSG_SIZE];
        struct synps_ecc_status stat;
        const struct synps_platform_data *p_data;
@@ -408,7 +411,8 @@ out:
 static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 {
        struct synps_ecc_status *p;
-       u32 regval, clearval = 0;
+       u32 regval, clearval;
+       unsigned long flags;
        void __iomem *base;
 
        base = priv->baseaddr;
@@ -452,10 +456,14 @@ ue_err:
        p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
        p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 out:
-       clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
-       clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
+       spin_lock_irqsave(&priv->reglock, flags);
+
+       clearval = readl(base + ECC_CLR_OFST) |
+                  ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
+                  ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
        writel(clearval, base + ECC_CLR_OFST);
-       writel(0x0, base + ECC_CLR_OFST);
+
+       spin_unlock_irqrestore(&priv->reglock, flags);
 
        return 0;
 }
@@ -515,24 +523,41 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
 
 static void enable_intr(struct synps_edac_priv *priv)
 {
+       unsigned long flags;
+
        /* Enable UE/CE Interrupts */
-       if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-               writel(DDR_UE_MASK | DDR_CE_MASK,
-                      priv->baseaddr + ECC_CLR_OFST);
-       else
+       if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
                writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
                       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
 
+               return;
+       }
+
+       spin_lock_irqsave(&priv->reglock, flags);
+
+       writel(DDR_UE_MASK | DDR_CE_MASK,
+              priv->baseaddr + ECC_CLR_OFST);
+
+       spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 static void disable_intr(struct synps_edac_priv *priv)
 {
+       unsigned long flags;
+
        /* Disable UE/CE Interrupts */
-       if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-               writel(0x0, priv->baseaddr + ECC_CLR_OFST);
-       else
+       if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
                writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
                       priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+
+               return;
+       }
+
+       spin_lock_irqsave(&priv->reglock, flags);
+
+       writel(0, priv->baseaddr + ECC_CLR_OFST);
+
+       spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 /**
@@ -576,8 +601,6 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
        /* v3.0 of the controller does not have this register */
        if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
                writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
-       else
-               enable_intr(priv);
 
        return IRQ_HANDLED;
 }
@@ -1357,6 +1380,7 @@ static int mc_probe(struct platform_device *pdev)
        priv = mci->pvt_info;
        priv->baseaddr = baseaddr;
        priv->p_data = p_data;
+       spin_lock_init(&priv->reglock);
 
        mc_init(mci, pdev);
 
index 1688a5050f63a4e2754aa3b49974dd6f9bc57fa7..a556d23e8261c6df566bcccf3b538478ebba659c 100644 (file)
@@ -425,7 +425,7 @@ static void handle_error(struct mem_ctl_info *mci, struct ecc_status *stat)
                         convert_to_physical(priv, pinf), pinf.burstpos);
 
                edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
-                                    priv->ce_cnt, 0, 0, 0, 0, 0, -1,
+                                    1, 0, 0, 0, 0, 0, -1,
                                     priv->message, "");
        }
 
@@ -438,7 +438,7 @@ static void handle_error(struct mem_ctl_info *mci, struct ecc_status *stat)
                         convert_to_physical(priv, pinf), pinf.burstpos);
 
                edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
-                                    priv->ue_cnt, 0, 0, 0, 0, 0, -1,
+                                    1, 0, 0, 0, 0, 0, -1,
                                     priv->message, "");
        }
 
@@ -865,6 +865,9 @@ static ssize_t inject_data_ue_store(struct file *file, const char __user *data,
        for (i = 0; i < NUM_UE_BITPOS; i++)
                token[i] = strsep(&pbuf, ",");
 
+       if (!token[0] || !token[1])
+               return -EFAULT;
+
        ret = kstrtou8(token[0], 0, &ue0);
        if (ret)
                return ret;
@@ -1135,8 +1138,7 @@ static int mc_probe(struct platform_device *pdev)
        }
 
        rc = xlnx_register_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1,
-                                XPM_EVENT_ERROR_MASK_DDRMC_CR | XPM_EVENT_ERROR_MASK_DDRMC_NCR |
-                                XPM_EVENT_ERROR_MASK_NOC_CR | XPM_EVENT_ERROR_MASK_NOC_NCR,
+                                XPM_EVENT_ERROR_MASK_DDRMC_CR | XPM_EVENT_ERROR_MASK_DDRMC_NCR,
                                 false, err_callback, mci);
        if (rc) {
                if (rc == -EACCES)
@@ -1173,8 +1175,6 @@ static void mc_remove(struct platform_device *pdev)
 
        xlnx_unregister_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1,
                              XPM_EVENT_ERROR_MASK_DDRMC_CR |
-                             XPM_EVENT_ERROR_MASK_NOC_CR |
-                             XPM_EVENT_ERROR_MASK_NOC_NCR |
                              XPM_EVENT_ERROR_MASK_DDRMC_NCR, err_callback, mci);
        edac_mc_del_mc(&pdev->dev);
        edac_mc_free(mci);
index c8bbf90209f5a5c2d34d04fb6032b33f9348f574..a66b3be502a9bf57b3a068cbe9183290dc696ac7 100644 (file)
@@ -44,17 +44,16 @@ config EISA_PCI_EISA
 
          When in doubt, say Y.
 
-# Using EISA_VIRTUAL_ROOT on something other than an Alpha or
-# an X86 may lead to crashes...
+# Using EISA_VIRTUAL_ROOT on something other than an X86 may lead
+# to crashes...
 
 config EISA_VIRTUAL_ROOT
        bool "EISA virtual root device"
-       depends on EISA && (ALPHA || X86)
+       depends on EISA && X86
        default y
        help
          Activate this option if your system only have EISA bus
-         (no PCI slots). The Alpha Jensen is an example of such
-         a system.
+         (no PCI slots).
 
          When in doubt, say Y.
 
index 37e6dd219c37a4557d5e3bde95917e1aa1bf3316..cd9515d9d8f0b8906d0f8e0244f19596528b1335 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 
-#if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_EISA_VLB_PRIMING)
+#if defined(CONFIG_EISA_VLB_PRIMING)
 #define EISA_FORCE_PROBE_DEFAULT 1
 #else
 #define EISA_FORCE_PROBE_DEFAULT 0
index b0d671db178a85b6ab98de29f05b994db99a8697..ea31ac7ac1ca931a569af239dbaa2052448e8df5 100644 (file)
@@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, char __user *data, size_t user_length)
        if (atomic_read(&buffer->size) == 0)
                return -ENODEV;
 
-       /* FIXME: Check length <= user_length. */
+       length = buffer->head->length;
+
+       if (length > user_length)
+               return 0;
 
        end = buffer->data + buffer->capacity;
-       length = buffer->head->length;
 
        if (&buffer->head->data[length] < end) {
                if (copy_to_user(data, buffer->head->data, length))
index 38d19410a2be68cab9f382d48ab7f15493c42af0..b9ae0340b8a70343185fe97364229dab4f72101c 100644 (file)
@@ -1556,6 +1556,8 @@ static int handle_at_packet(struct context *context,
 #define HEADER_GET_DATA_LENGTH(q)      (((q) >> 16) & 0xffff)
 #define HEADER_GET_EXTENDED_TCODE(q)   (((q) >> 0) & 0xffff)
 
+static u32 get_cycle_time(struct fw_ohci *ohci);
+
 static void handle_local_rom(struct fw_ohci *ohci,
                             struct fw_packet *packet, u32 csr)
 {
@@ -1580,6 +1582,8 @@ static void handle_local_rom(struct fw_ohci *ohci,
                                 (void *) ohci->config_rom + i, length);
        }
 
+       // Timestamping on behalf of the hardware.
+       response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
        fw_core_handle_response(&ohci->card, &response);
 }
 
@@ -1628,6 +1632,8 @@ static void handle_local_lock(struct fw_ohci *ohci,
        fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
  out:
+       // Timestamping on behalf of the hardware.
+       response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
        fw_core_handle_response(&ohci->card, &response);
 }
 
@@ -1670,8 +1676,6 @@ static void handle_local_request(struct context *ctx, struct fw_packet *packet)
        }
 }
 
-static u32 get_cycle_time(struct fw_ohci *ohci);
-
 static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
 {
        unsigned long flags;
index 9bc2e10381afd9cc6f97d6dd50510c8daa092b5b..1609247cfafcf7b3abc15c9d8e2b18e0f2bc506f 100644 (file)
@@ -101,11 +101,12 @@ struct ffa_drv_info {
        bool bitmap_created;
        bool notif_enabled;
        unsigned int sched_recv_irq;
+       unsigned int notif_pend_irq;
        unsigned int cpuhp_state;
        struct ffa_pcpu_irq __percpu *irq_pcpu;
        struct workqueue_struct *notif_pcpu_wq;
        struct work_struct notif_pcpu_work;
-       struct work_struct irq_work;
+       struct work_struct sched_recv_irq_work;
        struct xarray partition_info;
        DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
        struct mutex notify_lock; /* lock to protect notifier hashtable  */
@@ -344,6 +345,38 @@ static int ffa_msg_send_direct_req(u16 src_id, u16 dst_id, bool mode_32bit,
        return -EINVAL;
 }
 
+static int ffa_msg_send2(u16 src_id, u16 dst_id, void *buf, size_t sz)
+{
+       u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
+       struct ffa_indirect_msg_hdr *msg;
+       ffa_value_t ret;
+       int retval = 0;
+
+       if (sz > (RXTX_BUFFER_SIZE - sizeof(*msg)))
+               return -ERANGE;
+
+       mutex_lock(&drv_info->tx_lock);
+
+       msg = drv_info->tx_buffer;
+       msg->flags = 0;
+       msg->res0 = 0;
+       msg->offset = sizeof(*msg);
+       msg->send_recv_id = src_dst_ids;
+       msg->size = sz;
+       memcpy((u8 *)msg + msg->offset, buf, sz);
+
+       /* flags = 0, sender VMID = 0 works for both physical/virtual NS */
+       invoke_ffa_fn((ffa_value_t){
+                     .a0 = FFA_MSG_SEND2, .a1 = 0, .a2 = 0
+                     }, &ret);
+
+       if (ret.a0 == FFA_ERROR)
+               retval = ffa_to_linux_errno((int)ret.a2);
+
+       mutex_unlock(&drv_info->tx_lock);
+       return retval;
+}
+
 static int ffa_mem_first_frag(u32 func_id, phys_addr_t buf, u32 buf_sz,
                              u32 frag_len, u32 len, u64 *handle)
 {
@@ -870,6 +903,11 @@ static int ffa_sync_send_receive(struct ffa_device *dev,
                                       dev->mode_32bit, data);
 }
 
+static int ffa_indirect_msg_send(struct ffa_device *dev, void *buf, size_t sz)
+{
+       return ffa_msg_send2(drv_info->vm_id, dev->vm_id, buf, sz);
+}
+
 static int ffa_memory_share(struct ffa_mem_ops_args *args)
 {
        if (drv_info->mem_ops_native)
@@ -1108,7 +1146,7 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
        }
 }
 
-static void notif_pcpu_irq_work_fn(struct work_struct *work)
+static void notif_get_and_handle(void *unused)
 {
        int rc;
        struct ffa_notify_bitmaps bitmaps;
@@ -1131,10 +1169,17 @@ ffa_self_notif_handle(u16 vcpu, bool is_per_vcpu, void *cb_data)
        struct ffa_drv_info *info = cb_data;
 
        if (!is_per_vcpu)
-               notif_pcpu_irq_work_fn(&info->notif_pcpu_work);
+               notif_get_and_handle(info);
        else
-               queue_work_on(vcpu, info->notif_pcpu_wq,
-                             &info->notif_pcpu_work);
+               smp_call_function_single(vcpu, notif_get_and_handle, info, 0);
+}
+
+static void notif_pcpu_irq_work_fn(struct work_struct *work)
+{
+       struct ffa_drv_info *info = container_of(work, struct ffa_drv_info,
+                                                notif_pcpu_work);
+
+       ffa_self_notif_handle(smp_processor_id(), true, info);
 }
 
 static const struct ffa_info_ops ffa_drv_info_ops = {
@@ -1145,6 +1190,7 @@ static const struct ffa_info_ops ffa_drv_info_ops = {
 static const struct ffa_msg_ops ffa_drv_msg_ops = {
        .mode_32bit_set = ffa_mode_32bit_set,
        .sync_send_receive = ffa_sync_send_receive,
+       .indirect_send = ffa_indirect_msg_send,
 };
 
 static const struct ffa_mem_ops ffa_drv_mem_ops = {
@@ -1227,6 +1273,8 @@ static int ffa_setup_partitions(void)
                        continue;
                }
 
+               ffa_dev->properties = tpbuf->properties;
+
                if (drv_info->version > FFA_VERSION_1_0 &&
                    !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
                        ffa_mode_32bit_set(ffa_dev);
@@ -1291,12 +1339,23 @@ static void ffa_partitions_cleanup(void)
 #define FFA_FEAT_SCHEDULE_RECEIVER_INT         (2)
 #define FFA_FEAT_MANAGED_EXIT_INT              (3)
 
-static irqreturn_t irq_handler(int irq, void *irq_data)
+static irqreturn_t ffa_sched_recv_irq_handler(int irq, void *irq_data)
+{
+       struct ffa_pcpu_irq *pcpu = irq_data;
+       struct ffa_drv_info *info = pcpu->info;
+
+       queue_work(info->notif_pcpu_wq, &info->sched_recv_irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t notif_pend_irq_handler(int irq, void *irq_data)
 {
        struct ffa_pcpu_irq *pcpu = irq_data;
        struct ffa_drv_info *info = pcpu->info;
 
-       queue_work(info->notif_pcpu_wq, &info->irq_work);
+       queue_work_on(smp_processor_id(), info->notif_pcpu_wq,
+                     &info->notif_pcpu_work);
 
        return IRQ_HANDLED;
 }
@@ -1306,15 +1365,23 @@ static void ffa_sched_recv_irq_work_fn(struct work_struct *work)
        ffa_notification_info_get();
 }
 
-static int ffa_sched_recv_irq_map(void)
+static int ffa_irq_map(u32 id)
 {
-       int ret, irq, sr_intid;
+       char *err_str;
+       int ret, irq, intid;
 
-       /* The returned sr_intid is assumed to be SGI donated to NS world */
-       ret = ffa_features(FFA_FEAT_SCHEDULE_RECEIVER_INT, 0, &sr_intid, NULL);
+       if (id == FFA_FEAT_NOTIFICATION_PENDING_INT)
+               err_str = "Notification Pending Interrupt";
+       else if (id == FFA_FEAT_SCHEDULE_RECEIVER_INT)
+               err_str = "Schedule Receiver Interrupt";
+       else
+               err_str = "Unknown ID";
+
+       /* The returned intid is assumed to be SGI donated to NS world */
+       ret = ffa_features(id, 0, &intid, NULL);
        if (ret < 0) {
                if (ret != -EOPNOTSUPP)
-                       pr_err("Failed to retrieve scheduler Rx interrupt\n");
+                       pr_err("Failed to retrieve FF-A %s %u\n", err_str, id);
                return ret;
        }
 
@@ -1329,12 +1396,12 @@ static int ffa_sched_recv_irq_map(void)
 
                oirq.np = gic;
                oirq.args_count = 1;
-               oirq.args[0] = sr_intid;
+               oirq.args[0] = intid;
                irq = irq_create_of_mapping(&oirq);
                of_node_put(gic);
 #ifdef CONFIG_ACPI
        } else {
-               irq = acpi_register_gsi(NULL, sr_intid, ACPI_EDGE_SENSITIVE,
+               irq = acpi_register_gsi(NULL, intid, ACPI_EDGE_SENSITIVE,
                                        ACPI_ACTIVE_HIGH);
 #endif
        }
@@ -1347,23 +1414,28 @@ static int ffa_sched_recv_irq_map(void)
        return irq;
 }
 
-static void ffa_sched_recv_irq_unmap(void)
+static void ffa_irq_unmap(unsigned int irq)
 {
-       if (drv_info->sched_recv_irq) {
-               irq_dispose_mapping(drv_info->sched_recv_irq);
-               drv_info->sched_recv_irq = 0;
-       }
+       if (!irq)
+               return;
+       irq_dispose_mapping(irq);
 }
 
 static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu)
 {
-       enable_percpu_irq(drv_info->sched_recv_irq, IRQ_TYPE_NONE);
+       if (drv_info->sched_recv_irq)
+               enable_percpu_irq(drv_info->sched_recv_irq, IRQ_TYPE_NONE);
+       if (drv_info->notif_pend_irq)
+               enable_percpu_irq(drv_info->notif_pend_irq, IRQ_TYPE_NONE);
        return 0;
 }
 
 static int ffa_cpuhp_pcpu_irq_disable(unsigned int cpu)
 {
-       disable_percpu_irq(drv_info->sched_recv_irq);
+       if (drv_info->sched_recv_irq)
+               disable_percpu_irq(drv_info->sched_recv_irq);
+       if (drv_info->notif_pend_irq)
+               disable_percpu_irq(drv_info->notif_pend_irq);
        return 0;
 }
 
@@ -1382,13 +1454,16 @@ static void ffa_uninit_pcpu_irq(void)
        if (drv_info->sched_recv_irq)
                free_percpu_irq(drv_info->sched_recv_irq, drv_info->irq_pcpu);
 
+       if (drv_info->notif_pend_irq)
+               free_percpu_irq(drv_info->notif_pend_irq, drv_info->irq_pcpu);
+
        if (drv_info->irq_pcpu) {
                free_percpu(drv_info->irq_pcpu);
                drv_info->irq_pcpu = NULL;
        }
 }
 
-static int ffa_init_pcpu_irq(unsigned int irq)
+static int ffa_init_pcpu_irq(void)
 {
        struct ffa_pcpu_irq __percpu *irq_pcpu;
        int ret, cpu;
@@ -1402,13 +1477,31 @@ static int ffa_init_pcpu_irq(unsigned int irq)
 
        drv_info->irq_pcpu = irq_pcpu;
 
-       ret = request_percpu_irq(irq, irq_handler, "ARM-FFA", irq_pcpu);
-       if (ret) {
-               pr_err("Error registering notification IRQ %d: %d\n", irq, ret);
-               return ret;
+       if (drv_info->sched_recv_irq) {
+               ret = request_percpu_irq(drv_info->sched_recv_irq,
+                                        ffa_sched_recv_irq_handler,
+                                        "ARM-FFA-SRI", irq_pcpu);
+               if (ret) {
+                       pr_err("Error registering percpu SRI nIRQ %d : %d\n",
+                              drv_info->sched_recv_irq, ret);
+                       drv_info->sched_recv_irq = 0;
+                       return ret;
+               }
        }
 
-       INIT_WORK(&drv_info->irq_work, ffa_sched_recv_irq_work_fn);
+       if (drv_info->notif_pend_irq) {
+               ret = request_percpu_irq(drv_info->notif_pend_irq,
+                                        notif_pend_irq_handler,
+                                        "ARM-FFA-NPI", irq_pcpu);
+               if (ret) {
+                       pr_err("Error registering percpu NPI nIRQ %d : %d\n",
+                              drv_info->notif_pend_irq, ret);
+                       drv_info->notif_pend_irq = 0;
+                       return ret;
+               }
+       }
+
+       INIT_WORK(&drv_info->sched_recv_irq_work, ffa_sched_recv_irq_work_fn);
        INIT_WORK(&drv_info->notif_pcpu_work, notif_pcpu_irq_work_fn);
        drv_info->notif_pcpu_wq = create_workqueue("ffa_pcpu_irq_notification");
        if (!drv_info->notif_pcpu_wq)
@@ -1428,7 +1521,10 @@ static int ffa_init_pcpu_irq(unsigned int irq)
 static void ffa_notifications_cleanup(void)
 {
        ffa_uninit_pcpu_irq();
-       ffa_sched_recv_irq_unmap();
+       ffa_irq_unmap(drv_info->sched_recv_irq);
+       drv_info->sched_recv_irq = 0;
+       ffa_irq_unmap(drv_info->notif_pend_irq);
+       drv_info->notif_pend_irq = 0;
 
        if (drv_info->bitmap_created) {
                ffa_notification_bitmap_destroy();
@@ -1439,30 +1535,31 @@ static void ffa_notifications_cleanup(void)
 
 static void ffa_notifications_setup(void)
 {
-       int ret, irq;
+       int ret;
 
        ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL);
-       if (ret) {
-               pr_info("Notifications not supported, continuing with it ..\n");
-               return;
-       }
+       if (!ret) {
+               ret = ffa_notification_bitmap_create();
+               if (ret) {
+                       pr_err("Notification bitmap create error %d\n", ret);
+                       return;
+               }
 
-       ret = ffa_notification_bitmap_create();
-       if (ret) {
-               pr_info("Notification bitmap create error %d\n", ret);
-               return;
+               drv_info->bitmap_created = true;
        }
-       drv_info->bitmap_created = true;
 
-       irq = ffa_sched_recv_irq_map();
-       if (irq <= 0) {
-               ret = irq;
-               goto cleanup;
-       }
+       ret = ffa_irq_map(FFA_FEAT_SCHEDULE_RECEIVER_INT);
+       if (ret > 0)
+               drv_info->sched_recv_irq = ret;
+
+       ret = ffa_irq_map(FFA_FEAT_NOTIFICATION_PENDING_INT);
+       if (ret > 0)
+               drv_info->notif_pend_irq = ret;
 
-       drv_info->sched_recv_irq = irq;
+       if (!drv_info->sched_recv_irq && !drv_info->notif_pend_irq)
+               goto cleanup;
 
-       ret = ffa_init_pcpu_irq(irq);
+       ret = ffa_init_pcpu_irq();
        if (ret)
                goto cleanup;
 
index a7bc4796519c4a63934e0d40611d0aa3c403b33a..fd59f58ce8a2dd52f52eccec59642a1151e7b3ce 100644 (file)
@@ -10,7 +10,8 @@ scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o
 scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
-scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
+scmi-protocols-y := base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
+scmi-protocols-y += pinctrl.o
 scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
index 6affbfdd1dec1aeedb82dc53adbef3d182e33d02..b5ac25dbc1cac34e76afda986c2591f6f0c4054d 100644 (file)
@@ -301,6 +301,17 @@ extern const struct scmi_desc scmi_optee_desc;
 
 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv);
 
+enum scmi_bad_msg {
+       MSG_UNEXPECTED = -1,
+       MSG_INVALID = -2,
+       MSG_UNKNOWN = -3,
+       MSG_NOMEM = -4,
+       MSG_MBOX_SPURIOUS = -5,
+};
+
+void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr,
+                           enum scmi_bad_msg err);
+
 /* shmem related declarations */
 struct scmi_shared_mem;
 
index 2709598f3008908ecc7d377508bb99eedbb6f1b6..6b6957f4743fec2d906ba32225d7c6fd9e05ca36 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/processor.h>
 #include <linux/refcount.h>
 #include <linux/slab.h>
+#include <linux/xarray.h>
 
 #include "common.h"
 #include "notify.h"
@@ -44,8 +45,7 @@
 
 static DEFINE_IDA(scmi_id);
 
-static DEFINE_IDR(scmi_protocols);
-static DEFINE_SPINLOCK(protocol_lock);
+static DEFINE_XARRAY(scmi_protocols);
 
 /* List of all SCMI devices active in system */
 static LIST_HEAD(scmi_list);
@@ -194,11 +194,94 @@ struct scmi_info {
 #define bus_nb_to_scmi_info(nb)        container_of(nb, struct scmi_info, bus_nb)
 #define req_nb_to_scmi_info(nb)        container_of(nb, struct scmi_info, dev_req_nb)
 
-static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
+static unsigned long
+scmi_vendor_protocol_signature(unsigned int protocol_id, char *vendor_id,
+                              char *sub_vendor_id, u32 impl_ver)
 {
-       const struct scmi_protocol *proto;
+       char *signature, *p;
+       unsigned long hash = 0;
 
-       proto = idr_find(&scmi_protocols, protocol_id);
+       /* vendor_id/sub_vendor_id guaranteed <= SCMI_SHORT_NAME_MAX_SIZE */
+       signature = kasprintf(GFP_KERNEL, "%02X|%s|%s|0x%08X", protocol_id,
+                             vendor_id ?: "", sub_vendor_id ?: "", impl_ver);
+       if (!signature)
+               return 0;
+
+       p = signature;
+       while (*p)
+               hash = partial_name_hash(tolower(*p++), hash);
+       hash = end_name_hash(hash);
+
+       kfree(signature);
+
+       return hash;
+}
+
+static unsigned long
+scmi_protocol_key_calculate(int protocol_id, char *vendor_id,
+                           char *sub_vendor_id, u32 impl_ver)
+{
+       if (protocol_id < SCMI_PROTOCOL_VENDOR_BASE)
+               return protocol_id;
+       else
+               return scmi_vendor_protocol_signature(protocol_id, vendor_id,
+                                                     sub_vendor_id, impl_ver);
+}
+
+static const struct scmi_protocol *
+__scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
+                             char *sub_vendor_id, u32 impl_ver)
+{
+       unsigned long key;
+       struct scmi_protocol *proto = NULL;
+
+       key = scmi_protocol_key_calculate(protocol_id, vendor_id,
+                                         sub_vendor_id, impl_ver);
+       if (key)
+               proto = xa_load(&scmi_protocols, key);
+
+       return proto;
+}
+
+static const struct scmi_protocol *
+scmi_vendor_protocol_lookup(int protocol_id, char *vendor_id,
+                           char *sub_vendor_id, u32 impl_ver)
+{
+       const struct scmi_protocol *proto = NULL;
+
+       /* Searching for closest match ...*/
+       proto = __scmi_vendor_protocol_lookup(protocol_id, vendor_id,
+                                             sub_vendor_id, impl_ver);
+       if (proto)
+               return proto;
+
+       /* Any match just on vendor/sub_vendor ? */
+       if (impl_ver) {
+               proto = __scmi_vendor_protocol_lookup(protocol_id, vendor_id,
+                                                     sub_vendor_id, 0);
+               if (proto)
+                       return proto;
+       }
+
+       /* Any match just on the vendor ? */
+       if (sub_vendor_id)
+               proto = __scmi_vendor_protocol_lookup(protocol_id, vendor_id,
+                                                     NULL, 0);
+       return proto;
+}
+
+static const struct scmi_protocol *
+scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
+{
+       const struct scmi_protocol *proto = NULL;
+
+       if (protocol_id < SCMI_PROTOCOL_VENDOR_BASE)
+               proto = xa_load(&scmi_protocols, protocol_id);
+       else
+               proto = scmi_vendor_protocol_lookup(protocol_id,
+                                                   version->vendor_id,
+                                                   version->sub_vendor_id,
+                                                   version->impl_ver);
        if (!proto || !try_module_get(proto->owner)) {
                pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
                return NULL;
@@ -206,21 +289,46 @@ static const struct scmi_protocol *scmi_protocol_get(int protocol_id)
 
        pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
 
+       if (protocol_id >= SCMI_PROTOCOL_VENDOR_BASE)
+               pr_info("Loaded SCMI Vendor Protocol 0x%x - %s %s %X\n",
+                       protocol_id, proto->vendor_id ?: "",
+                       proto->sub_vendor_id ?: "", proto->impl_ver);
+
        return proto;
 }
 
-static void scmi_protocol_put(int protocol_id)
+static void scmi_protocol_put(const struct scmi_protocol *proto)
 {
-       const struct scmi_protocol *proto;
-
-       proto = idr_find(&scmi_protocols, protocol_id);
        if (proto)
                module_put(proto->owner);
 }
 
+static int scmi_vendor_protocol_check(const struct scmi_protocol *proto)
+{
+       if (!proto->vendor_id) {
+               pr_err("missing vendor_id for protocol 0x%x\n", proto->id);
+               return -EINVAL;
+       }
+
+       if (strlen(proto->vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
+               pr_err("malformed vendor_id for protocol 0x%x\n", proto->id);
+               return -EINVAL;
+       }
+
+       if (proto->sub_vendor_id &&
+           strlen(proto->sub_vendor_id) >= SCMI_SHORT_NAME_MAX_SIZE) {
+               pr_err("malformed sub_vendor_id for protocol 0x%x\n",
+                      proto->id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int scmi_protocol_register(const struct scmi_protocol *proto)
 {
        int ret;
+       unsigned long key;
 
        if (!proto) {
                pr_err("invalid protocol\n");
@@ -232,12 +340,23 @@ int scmi_protocol_register(const struct scmi_protocol *proto)
                return -EINVAL;
        }
 
-       spin_lock(&protocol_lock);
-       ret = idr_alloc(&scmi_protocols, (void *)proto,
-                       proto->id, proto->id + 1, GFP_ATOMIC);
-       spin_unlock(&protocol_lock);
-       if (ret != proto->id) {
-               pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
+       if (proto->id >= SCMI_PROTOCOL_VENDOR_BASE &&
+           scmi_vendor_protocol_check(proto))
+               return -EINVAL;
+
+       /*
+        * Calculate a protocol key to register this protocol with the core;
+        * key value 0 is considered invalid.
+        */
+       key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
+                                         proto->sub_vendor_id,
+                                         proto->impl_ver);
+       if (!key)
+               return -EINVAL;
+
+       ret = xa_insert(&scmi_protocols, key, (void *)proto, GFP_KERNEL);
+       if (ret) {
+               pr_err("unable to allocate SCMI protocol slot for 0x%x - err %d\n",
                       proto->id, ret);
                return ret;
        }
@@ -250,9 +369,15 @@ EXPORT_SYMBOL_GPL(scmi_protocol_register);
 
 void scmi_protocol_unregister(const struct scmi_protocol *proto)
 {
-       spin_lock(&protocol_lock);
-       idr_remove(&scmi_protocols, proto->id);
-       spin_unlock(&protocol_lock);
+       unsigned long key;
+
+       key = scmi_protocol_key_calculate(proto->id, proto->vendor_id,
+                                         proto->sub_vendor_id,
+                                         proto->impl_ver);
+       if (!key)
+               return;
+
+       xa_erase(&scmi_protocols, key);
 
        pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);
 }
@@ -696,6 +821,45 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo, u16 xfer_id)
        return xfer ?: ERR_PTR(-EINVAL);
 }
 
+/**
+ * scmi_bad_message_trace  - A helper to trace weird messages
+ *
+ * @cinfo: A reference to the channel descriptor on which the message was
+ *        received
+ * @msg_hdr: Message header to track
+ * @err: A specific error code used as a status value in traces.
+ *
+ * This helper can be used to trace any kind of weird, incomplete, unexpected,
+ * timed-out message that arrives and as such, can be traced only referring to
+ * the header content, since the payload is missing/unreliable.
+ */
+void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr,
+                           enum scmi_bad_msg err)
+{
+       char *tag;
+       struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+
+       switch (MSG_XTRACT_TYPE(msg_hdr)) {
+       case MSG_TYPE_COMMAND:
+               tag = "!RESP";
+               break;
+       case MSG_TYPE_DELAYED_RESP:
+               tag = "!DLYD";
+               break;
+       case MSG_TYPE_NOTIFICATION:
+               tag = "!NOTI";
+               break;
+       default:
+               tag = "!UNKN";
+               break;
+       }
+
+       trace_scmi_msg_dump(info->id, cinfo->id,
+                           MSG_XTRACT_PROT_ID(msg_hdr),
+                           MSG_XTRACT_ID(msg_hdr), tag,
+                           MSG_XTRACT_TOKEN(msg_hdr), err, NULL, 0);
+}
+
 /**
  * scmi_msg_response_validate  - Validate message type against state of related
  * xfer
@@ -822,6 +986,9 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
                        "Message for %d type %d is not expected!\n",
                        xfer_id, msg_type);
                spin_unlock_irqrestore(&minfo->xfer_lock, flags);
+
+               scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNEXPECTED);
+
                return xfer;
        }
        refcount_inc(&xfer->users);
@@ -846,6 +1013,9 @@ scmi_xfer_command_acquire(struct scmi_chan_info *cinfo, u32 msg_hdr)
                dev_err(cinfo->dev,
                        "Invalid message type:%d for %d - HDR:0x%X  state:%d\n",
                        msg_type, xfer_id, msg_hdr, xfer->state);
+
+               scmi_bad_message_trace(cinfo, msg_hdr, MSG_INVALID);
+
                /* On error the refcount incremented above has to be dropped */
                __scmi_xfer_put(minfo, xfer);
                xfer = ERR_PTR(-EINVAL);
@@ -882,6 +1052,9 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
        if (IS_ERR(xfer)) {
                dev_err(dev, "failed to get free message slot (%ld)\n",
                        PTR_ERR(xfer));
+
+               scmi_bad_message_trace(cinfo, msg_hdr, MSG_NOMEM);
+
                scmi_clear_channel(info, cinfo);
                return;
        }
@@ -1001,6 +1174,7 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv)
                break;
        default:
                WARN_ONCE(1, "received unknown msg_type:%d\n", msg_type);
+               scmi_bad_message_trace(cinfo, msg_hdr, MSG_UNKNOWN);
                break;
        }
 }
@@ -1488,6 +1662,20 @@ out:
        return ret;
 }
 
+/**
+ * scmi_common_get_max_msg_size  - Get maximum message size
+ * @ph: A protocol handle reference.
+ *
+ * Return: Maximum message size for the current protocol.
+ */
+static int scmi_common_get_max_msg_size(const struct scmi_protocol_handle *ph)
+{
+       const struct scmi_protocol_instance *pi = ph_to_pi(ph);
+       struct scmi_info *info = handle_to_scmi_info(pi->handle);
+
+       return info->desc->max_msg_size;
+}
+
 /**
  * struct scmi_iterator  - Iterator descriptor
  * @msg: A reference to the message TX buffer; filled by @prepare_message with
@@ -1799,6 +1987,7 @@ static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
 
 static const struct scmi_proto_helpers_ops helpers_ops = {
        .extended_name_get = scmi_common_extended_name_get,
+       .get_max_msg_size = scmi_common_get_max_msg_size,
        .iter_response_init = scmi_iterator_init,
        .iter_response_run = scmi_iterator_run,
        .protocol_msg_check = scmi_protocol_msg_check,
@@ -1891,7 +2080,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
        /* Protocol specific devres group */
        gid = devres_open_group(handle->dev, NULL, GFP_KERNEL);
        if (!gid) {
-               scmi_protocol_put(proto->id);
+               scmi_protocol_put(proto);
                goto out;
        }
 
@@ -1955,7 +2144,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
 
 clean:
        /* Take care to put the protocol module's owner before releasing all */
-       scmi_protocol_put(proto->id);
+       scmi_protocol_put(proto);
        devres_release_group(handle->dev, gid);
 out:
        return ERR_PTR(ret);
@@ -1989,7 +2178,7 @@ scmi_get_protocol_instance(const struct scmi_handle *handle, u8 protocol_id)
                const struct scmi_protocol *proto;
 
                /* Fails if protocol not registered on bus */
-               proto = scmi_protocol_get(protocol_id);
+               proto = scmi_protocol_get(protocol_id, &info->version);
                if (proto)
                        pi = scmi_alloc_init_protocol_instance(info, proto);
                else
@@ -2044,7 +2233,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id)
 
                idr_remove(&info->protocols, protocol_id);
 
-               scmi_protocol_put(protocol_id);
+               scmi_protocol_put(pi->proto);
 
                devres_release_group(handle->dev, gid);
                dev_dbg(handle->dev, "De-Initialized protocol: 0x%X\n",
@@ -2491,6 +2680,10 @@ scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node,
                        ret = 0;
        }
 
+       if (ret)
+               dev_err(info->dev,
+                       "failed to setup channel for protocol:0x%X\n", prot_id);
+
        return ret;
 }
 
@@ -2760,6 +2953,7 @@ static int scmi_debugfs_raw_mode_setup(struct scmi_info *info)
 static int scmi_probe(struct platform_device *pdev)
 {
        int ret;
+       char *err_str = "probe failure\n";
        struct scmi_handle *handle;
        const struct scmi_desc *desc;
        struct scmi_info *info;
@@ -2810,27 +3004,37 @@ static int scmi_probe(struct platform_device *pdev)
 
        if (desc->ops->link_supplier) {
                ret = desc->ops->link_supplier(dev);
-               if (ret)
+               if (ret) {
+                       err_str = "transport not ready\n";
                        goto clear_ida;
+               }
        }
 
        /* Setup all channels described in the DT at first */
        ret = scmi_channels_setup(info);
-       if (ret)
+       if (ret) {
+               err_str = "failed to setup channels\n";
                goto clear_ida;
+       }
 
        ret = bus_register_notifier(&scmi_bus_type, &info->bus_nb);
-       if (ret)
+       if (ret) {
+               err_str = "failed to register bus notifier\n";
                goto clear_txrx_setup;
+       }
 
        ret = blocking_notifier_chain_register(&scmi_requested_devices_nh,
                                               &info->dev_req_nb);
-       if (ret)
+       if (ret) {
+               err_str = "failed to register device notifier\n";
                goto clear_bus_notifier;
+       }
 
        ret = scmi_xfer_info_init(info);
-       if (ret)
+       if (ret) {
+               err_str = "failed to init xfers pool\n";
                goto clear_dev_req_notifier;
+       }
 
        if (scmi_top_dentry) {
                info->dbg = scmi_debugfs_common_setup(info);
@@ -2867,9 +3071,11 @@ static int scmi_probe(struct platform_device *pdev)
         */
        ret = scmi_protocol_acquire(handle, SCMI_PROTOCOL_BASE);
        if (ret) {
-               dev_err(dev, "unable to communicate with SCMI\n");
-               if (coex)
+               err_str = "unable to communicate with SCMI\n";
+               if (coex) {
+                       dev_err(dev, "%s", err_str);
                        return 0;
+               }
                goto notification_exit;
        }
 
@@ -2923,7 +3129,8 @@ clear_txrx_setup:
        scmi_cleanup_txrx_channels(info);
 clear_ida:
        ida_free(&scmi_id, info->id);
-       return ret;
+
+       return dev_err_probe(dev, ret, "%s", err_str);
 }
 
 static void scmi_remove(struct platform_device *pdev)
@@ -3127,6 +3334,7 @@ static int __init scmi_driver_init(void)
        scmi_voltage_register();
        scmi_system_register();
        scmi_powercap_register();
+       scmi_pinctrl_register();
 
        return platform_driver_register(&scmi_driver);
 }
@@ -3144,6 +3352,7 @@ static void __exit scmi_driver_exit(void)
        scmi_voltage_unregister();
        scmi_system_unregister();
        scmi_powercap_unregister();
+       scmi_pinctrl_unregister();
 
        scmi_transports_exit();
 
index b8d470417e8f99bb6408aba541bc4b89541ddf7c..615a3b2ad83d03c3ff8500d2544ab64d571ffcbf 100644 (file)
@@ -56,6 +56,9 @@ static void rx_callback(struct mbox_client *cl, void *m)
         */
        if (cl->knows_txdone && !shmem_channel_free(smbox->shmem)) {
                dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n");
+               scmi_bad_message_trace(smbox->cinfo,
+                                      shmem_read_header(smbox->shmem),
+                                      MSG_MBOX_SPURIOUS);
                return;
        }
 
index 27c52531194d0797ac0682f51bbad34a7cef479f..e160ecb22948fc7107d937e0bbd01261b3746532 100644 (file)
@@ -1513,17 +1513,12 @@ static int scmi_devm_notifier_register(struct scmi_device *sdev,
 static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
 {
        struct scmi_notifier_devres *dres = res;
-       struct scmi_notifier_devres *xres = data;
+       struct notifier_block *nb = data;
 
-       if (WARN_ON(!dres || !xres))
+       if (WARN_ON(!dres || !nb))
                return 0;
 
-       return dres->proto_id == xres->proto_id &&
-               dres->evt_id == xres->evt_id &&
-               dres->nb == xres->nb &&
-               ((!dres->src_id && !xres->src_id) ||
-                 (dres->src_id && xres->src_id &&
-                  dres->__src_id == xres->__src_id));
+       return dres->nb == nb;
 }
 
 /**
@@ -1531,10 +1526,6 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
  * notifier_block for an event
  * @sdev: A reference to an scmi_device whose embedded struct device is to
  *       be used for devres accounting.
- * @proto_id: Protocol ID
- * @evt_id: Event ID
- * @src_id: Source ID, when NULL register for events coming form ALL possible
- *         sources
  * @nb: A standard notifier block to register for the specified event
  *
  * Generic devres managed helper to explicitly un-register a notifier_block
@@ -1544,25 +1535,12 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data)
  * Return: 0 on Success
  */
 static int scmi_devm_notifier_unregister(struct scmi_device *sdev,
-                                        u8 proto_id, u8 evt_id,
-                                        const u32 *src_id,
                                         struct notifier_block *nb)
 {
        int ret;
-       struct scmi_notifier_devres dres;
-
-       dres.handle = sdev->handle;
-       dres.proto_id = proto_id;
-       dres.evt_id = evt_id;
-       if (src_id) {
-               dres.__src_id = *src_id;
-               dres.src_id = &dres.__src_id;
-       } else {
-               dres.src_id = NULL;
-       }
 
        ret = devres_release(&sdev->dev, scmi_devm_release_notifier,
-                            scmi_devm_notifier_match, &dres);
+                            scmi_devm_notifier_match, nb);
 
        WARN_ON(ret);
 
index 345fff167b52f5e1b87ced8cd854e96702e0734d..4b7f1cbb9b04d6b3388a9382cb8f2d315f1cc966 100644 (file)
@@ -387,8 +387,8 @@ process_response_opp(struct device *dev, struct perf_dom_info *dom,
 
        ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
        if (ret)
-               dev_warn(dev, "Failed to add opps_by_lvl at %d - ret:%d\n",
-                        opp->perf, ret);
+               dev_warn(dev, "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
+                        opp->perf, dom->info.name, ret);
 }
 
 static inline void
@@ -405,8 +405,8 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
 
        ret = xa_insert(&dom->opps_by_lvl, opp->perf, opp, GFP_KERNEL);
        if (ret)
-               dev_warn(dev, "Failed to add opps_by_lvl at %d - ret:%d\n",
-                        opp->perf, ret);
+               dev_warn(dev, "Failed to add opps_by_lvl at %d for %s - ret:%d\n",
+                        opp->perf, dom->info.name, ret);
 
        /* Note that PERF v4 reports always five 32-bit words */
        opp->indicative_freq = le32_to_cpu(r->opp[loop_idx].indicative_freq);
@@ -417,8 +417,8 @@ process_response_opp_v4(struct device *dev, struct perf_dom_info *dom,
                                GFP_KERNEL);
                if (ret)
                        dev_warn(dev,
-                                "Failed to add opps_by_idx at %d - ret:%d\n",
-                                opp->level_index, ret);
+                                "Failed to add opps_by_idx at %d for %s - ret:%d\n",
+                                opp->level_index, dom->info.name, ret);
 
                hash_add(dom->opps_by_freq, &opp->hash, opp->indicative_freq);
        }
@@ -879,7 +879,8 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph,
 
                ret = dev_pm_opp_add_dynamic(dev, &data);
                if (ret) {
-                       dev_warn(dev, "failed to add opp %luHz\n", freq);
+                       dev_warn(dev, "[%d][%s]: Failed to add OPP[%d] %lu\n",
+                                domain, dom->info.name, idx, freq);
                        dev_pm_opp_remove_all_dynamic(dev);
                        return ret;
                }
diff --git a/drivers/firmware/arm_scmi/pinctrl.c b/drivers/firmware/arm_scmi/pinctrl.c
new file mode 100644 (file)
index 0000000..a2a7f88
--- /dev/null
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Pinctrl Protocol
+ *
+ * Copyright (C) 2024 EPAM
+ * Copyright 2024 NXP
+ */
+
+#include <asm/byteorder.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "common.h"
+#include "protocols.h"
+
+/* Updated only after ALL the mandatory features for that version are merged */
+#define SCMI_PROTOCOL_SUPPORTED_VERSION                0x10000
+
+#define GET_GROUPS_NR(x)       le32_get_bits((x), GENMASK(31, 16))
+#define GET_PINS_NR(x)         le32_get_bits((x), GENMASK(15, 0))
+#define GET_FUNCTIONS_NR(x)    le32_get_bits((x), GENMASK(15, 0))
+
+#define EXT_NAME_FLAG(x)       le32_get_bits((x), BIT(31))
+#define NUM_ELEMS(x)           le32_get_bits((x), GENMASK(15, 0))
+
+#define REMAINING(x)           le32_get_bits((x), GENMASK(31, 16))
+#define RETURNED(x)            le32_get_bits((x), GENMASK(11, 0))
+
+#define CONFIG_FLAG_MASK       GENMASK(19, 18)
+#define SELECTOR_MASK          GENMASK(17, 16)
+#define SKIP_CONFIGS_MASK      GENMASK(15, 8)
+#define CONFIG_TYPE_MASK       GENMASK(7, 0)
+
+enum scmi_pinctrl_protocol_cmd {
+       PINCTRL_ATTRIBUTES = 0x3,
+       PINCTRL_LIST_ASSOCIATIONS = 0x4,
+       PINCTRL_SETTINGS_GET = 0x5,
+       PINCTRL_SETTINGS_CONFIGURE = 0x6,
+       PINCTRL_REQUEST = 0x7,
+       PINCTRL_RELEASE = 0x8,
+       PINCTRL_NAME_GET = 0x9,
+       PINCTRL_SET_PERMISSIONS = 0xa,
+};
+
+struct scmi_msg_settings_conf {
+       __le32 identifier;
+       __le32 function_id;
+       __le32 attributes;
+       __le32 configs[];
+};
+
+struct scmi_msg_settings_get {
+       __le32 identifier;
+       __le32 attributes;
+};
+
+struct scmi_resp_settings_get {
+       __le32 function_selected;
+       __le32 num_configs;
+       __le32 configs[];
+};
+
+struct scmi_msg_pinctrl_protocol_attributes {
+       __le32 attributes_low;
+       __le32 attributes_high;
+};
+
+struct scmi_msg_pinctrl_attributes {
+       __le32 identifier;
+       __le32 flags;
+};
+
+struct scmi_resp_pinctrl_attributes {
+       __le32 attributes;
+       u8 name[SCMI_SHORT_NAME_MAX_SIZE];
+};
+
+struct scmi_msg_pinctrl_list_assoc {
+       __le32 identifier;
+       __le32 flags;
+       __le32 index;
+};
+
+struct scmi_resp_pinctrl_list_assoc {
+       __le32 flags;
+       __le16 array[];
+};
+
+struct scmi_msg_request {
+       __le32 identifier;
+       __le32 flags;
+};
+
+struct scmi_group_info {
+       char name[SCMI_MAX_STR_SIZE];
+       bool present;
+       u32 *group_pins;
+       u32 nr_pins;
+};
+
+struct scmi_function_info {
+       char name[SCMI_MAX_STR_SIZE];
+       bool present;
+       u32 *groups;
+       u32 nr_groups;
+};
+
+struct scmi_pin_info {
+       char name[SCMI_MAX_STR_SIZE];
+       bool present;
+};
+
+struct scmi_pinctrl_info {
+       u32 version;
+       int nr_groups;
+       int nr_functions;
+       int nr_pins;
+       struct scmi_group_info *groups;
+       struct scmi_function_info *functions;
+       struct scmi_pin_info *pins;
+};
+
+static int scmi_pinctrl_attributes_get(const struct scmi_protocol_handle *ph,
+                                      struct scmi_pinctrl_info *pi)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_pinctrl_protocol_attributes *attr;
+
+       ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), &t);
+       if (ret)
+               return ret;
+
+       attr = t->rx.buf;
+
+       ret = ph->xops->do_xfer(ph, t);
+       if (!ret) {
+               pi->nr_functions = GET_FUNCTIONS_NR(attr->attributes_high);
+               pi->nr_groups = GET_GROUPS_NR(attr->attributes_low);
+               pi->nr_pins = GET_PINS_NR(attr->attributes_low);
+               if (pi->nr_pins == 0) {
+                       dev_warn(ph->dev, "returned zero pins\n");
+                       ret = -EINVAL;
+               }
+       }
+
+       ph->xops->xfer_put(ph, t);
+       return ret;
+}
+
+static int scmi_pinctrl_count_get(const struct scmi_protocol_handle *ph,
+                                 enum scmi_pinctrl_selector_type type)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       switch (type) {
+       case PIN_TYPE:
+               return pi->nr_pins;
+       case GROUP_TYPE:
+               return pi->nr_groups;
+       case FUNCTION_TYPE:
+               return pi->nr_functions;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int scmi_pinctrl_validate_id(const struct scmi_protocol_handle *ph,
+                                   u32 selector,
+                                   enum scmi_pinctrl_selector_type type)
+{
+       int value;
+
+       value = scmi_pinctrl_count_get(ph, type);
+       if (value < 0)
+               return value;
+
+       if (selector >= value || value == 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int scmi_pinctrl_attributes(const struct scmi_protocol_handle *ph,
+                                  enum scmi_pinctrl_selector_type type,
+                                  u32 selector, char *name,
+                                  u32 *n_elems)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_pinctrl_attributes *tx;
+       struct scmi_resp_pinctrl_attributes *rx;
+       bool ext_name_flag;
+
+       if (!name)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_validate_id(ph, selector, type);
+       if (ret)
+               return ret;
+
+       ret = ph->xops->xfer_get_init(ph, PINCTRL_ATTRIBUTES, sizeof(*tx),
+                                     sizeof(*rx), &t);
+       if (ret)
+               return ret;
+
+       tx = t->tx.buf;
+       rx = t->rx.buf;
+       tx->identifier = cpu_to_le32(selector);
+       tx->flags = cpu_to_le32(type);
+
+       ret = ph->xops->do_xfer(ph, t);
+       if (!ret) {
+               if (n_elems)
+                       *n_elems = NUM_ELEMS(rx->attributes);
+
+               strscpy(name, rx->name, SCMI_SHORT_NAME_MAX_SIZE);
+
+               ext_name_flag = !!EXT_NAME_FLAG(rx->attributes);
+       }
+
+       ph->xops->xfer_put(ph, t);
+
+       if (ret)
+               return ret;
+       /*
+        * If supported overwrite short name with the extended one;
+        * on error just carry on and use already provided short name.
+        */
+       if (ext_name_flag)
+               ret = ph->hops->extended_name_get(ph, PINCTRL_NAME_GET,
+                                                 selector, (u32 *)&type, name,
+                                                 SCMI_MAX_STR_SIZE);
+       return ret;
+}
+
+struct scmi_pinctrl_ipriv {
+       u32 selector;
+       enum scmi_pinctrl_selector_type type;
+       u32 *array;
+};
+
+static void iter_pinctrl_assoc_prepare_message(void *message,
+                                              u32 desc_index,
+                                              const void *priv)
+{
+       struct scmi_msg_pinctrl_list_assoc *msg = message;
+       const struct scmi_pinctrl_ipriv *p = priv;
+
+       msg->identifier = cpu_to_le32(p->selector);
+       msg->flags = cpu_to_le32(p->type);
+       msg->index = cpu_to_le32(desc_index);
+}
+
+static int iter_pinctrl_assoc_update_state(struct scmi_iterator_state *st,
+                                          const void *response, void *priv)
+{
+       const struct scmi_resp_pinctrl_list_assoc *r = response;
+
+       st->num_returned = RETURNED(r->flags);
+       st->num_remaining = REMAINING(r->flags);
+
+       return 0;
+}
+
+static int
+iter_pinctrl_assoc_process_response(const struct scmi_protocol_handle *ph,
+                                   const void *response,
+                                   struct scmi_iterator_state *st, void *priv)
+{
+       const struct scmi_resp_pinctrl_list_assoc *r = response;
+       struct scmi_pinctrl_ipriv *p = priv;
+
+       p->array[st->desc_index + st->loop_idx] =
+               le16_to_cpu(r->array[st->loop_idx]);
+
+       return 0;
+}
+
+static int scmi_pinctrl_list_associations(const struct scmi_protocol_handle *ph,
+                                         u32 selector,
+                                         enum scmi_pinctrl_selector_type type,
+                                         u16 size, u32 *array)
+{
+       int ret;
+       void *iter;
+       struct scmi_iterator_ops ops = {
+               .prepare_message = iter_pinctrl_assoc_prepare_message,
+               .update_state = iter_pinctrl_assoc_update_state,
+               .process_response = iter_pinctrl_assoc_process_response,
+       };
+       struct scmi_pinctrl_ipriv ipriv = {
+               .selector = selector,
+               .type = type,
+               .array = array,
+       };
+
+       if (!array || !size || type == PIN_TYPE)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_validate_id(ph, selector, type);
+       if (ret)
+               return ret;
+
+       iter = ph->hops->iter_response_init(ph, &ops, size,
+                                           PINCTRL_LIST_ASSOCIATIONS,
+                                           sizeof(struct scmi_msg_pinctrl_list_assoc),
+                                           &ipriv);
+       if (IS_ERR(iter))
+               return PTR_ERR(iter);
+
+       return ph->hops->iter_response_run(iter);
+}
+
+struct scmi_settings_get_ipriv {
+       u32 selector;
+       enum scmi_pinctrl_selector_type type;
+       bool get_all;
+       unsigned int *nr_configs;
+       enum scmi_pinctrl_conf_type *config_types;
+       u32 *config_values;
+};
+
+static void
+iter_pinctrl_settings_get_prepare_message(void *message, u32 desc_index,
+                                         const void *priv)
+{
+       struct scmi_msg_settings_get *msg = message;
+       const struct scmi_settings_get_ipriv *p = priv;
+       u32 attributes;
+
+       attributes = FIELD_PREP(SELECTOR_MASK, p->type);
+
+       if (p->get_all) {
+               attributes |= FIELD_PREP(CONFIG_FLAG_MASK, 1) |
+                       FIELD_PREP(SKIP_CONFIGS_MASK, desc_index);
+       } else {
+               attributes |= FIELD_PREP(CONFIG_TYPE_MASK, p->config_types[0]);
+       }
+
+       msg->attributes = cpu_to_le32(attributes);
+       msg->identifier = cpu_to_le32(p->selector);
+}
+
+static int
+iter_pinctrl_settings_get_update_state(struct scmi_iterator_state *st,
+                                      const void *response, void *priv)
+{
+       const struct scmi_resp_settings_get *r = response;
+       struct scmi_settings_get_ipriv *p = priv;
+
+       if (p->get_all) {
+               st->num_returned = le32_get_bits(r->num_configs, GENMASK(7, 0));
+               st->num_remaining = le32_get_bits(r->num_configs, GENMASK(31, 24));
+       } else {
+               st->num_returned = 1;
+               st->num_remaining = 0;
+       }
+
+       return 0;
+}
+
+static int
+iter_pinctrl_settings_get_process_response(const struct scmi_protocol_handle *ph,
+                                          const void *response,
+                                          struct scmi_iterator_state *st,
+                                          void *priv)
+{
+       const struct scmi_resp_settings_get *r = response;
+       struct scmi_settings_get_ipriv *p = priv;
+       u32 type = le32_get_bits(r->configs[st->loop_idx * 2], GENMASK(7, 0));
+       u32 val = le32_to_cpu(r->configs[st->loop_idx * 2 + 1]);
+
+       if (p->get_all) {
+               p->config_types[st->desc_index + st->loop_idx] = type;
+       } else {
+               if (p->config_types[0] != type)
+                       return -EINVAL;
+       }
+
+       p->config_values[st->desc_index + st->loop_idx] = val;
+       ++*p->nr_configs;
+
+       return 0;
+}
+
+static int
+scmi_pinctrl_settings_get(const struct scmi_protocol_handle *ph, u32 selector,
+                         enum scmi_pinctrl_selector_type type,
+                         unsigned int *nr_configs,
+                         enum scmi_pinctrl_conf_type *config_types,
+                         u32 *config_values)
+{
+       int ret;
+       void *iter;
+       unsigned int max_configs = *nr_configs;
+       struct scmi_iterator_ops ops = {
+               .prepare_message = iter_pinctrl_settings_get_prepare_message,
+               .update_state = iter_pinctrl_settings_get_update_state,
+               .process_response = iter_pinctrl_settings_get_process_response,
+       };
+       struct scmi_settings_get_ipriv ipriv = {
+               .selector = selector,
+               .type = type,
+               .get_all = (max_configs > 1),
+               .nr_configs = nr_configs,
+               .config_types = config_types,
+               .config_values = config_values,
+       };
+
+       if (!config_types || !config_values || type == FUNCTION_TYPE)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_validate_id(ph, selector, type);
+       if (ret)
+               return ret;
+
+       /* Prepare to count returned configs */
+       *nr_configs = 0;
+       iter = ph->hops->iter_response_init(ph, &ops, max_configs,
+                                           PINCTRL_SETTINGS_GET,
+                                           sizeof(struct scmi_msg_settings_get),
+                                           &ipriv);
+       if (IS_ERR(iter))
+               return PTR_ERR(iter);
+
+       return ph->hops->iter_response_run(iter);
+}
+
+static int scmi_pinctrl_settings_get_one(const struct scmi_protocol_handle *ph,
+                                        u32 selector,
+                                        enum scmi_pinctrl_selector_type type,
+                                        enum scmi_pinctrl_conf_type config_type,
+                                        u32 *config_value)
+{
+       unsigned int nr_configs = 1;
+
+       return scmi_pinctrl_settings_get(ph, selector, type, &nr_configs,
+                                        &config_type, config_value);
+}
+
+static int scmi_pinctrl_settings_get_all(const struct scmi_protocol_handle *ph,
+                                        u32 selector,
+                                        enum scmi_pinctrl_selector_type type,
+                                        unsigned int *nr_configs,
+                                        enum scmi_pinctrl_conf_type *config_types,
+                                        u32 *config_values)
+{
+       if (!nr_configs || *nr_configs == 0)
+               return -EINVAL;
+
+       return scmi_pinctrl_settings_get(ph, selector, type, nr_configs,
+                                        config_types, config_values);
+}
+
+static int
+scmi_pinctrl_settings_conf(const struct scmi_protocol_handle *ph,
+                          u32 selector,
+                          enum scmi_pinctrl_selector_type type,
+                          u32 nr_configs,
+                          enum scmi_pinctrl_conf_type *config_type,
+                          u32 *config_value)
+{
+       struct scmi_xfer *t;
+       struct scmi_msg_settings_conf *tx;
+       u32 attributes;
+       int ret, i;
+       u32 configs_in_chunk, conf_num = 0;
+       u32 chunk;
+       int max_msg_size = ph->hops->get_max_msg_size(ph);
+
+       if (!config_type || !config_value || type == FUNCTION_TYPE)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_validate_id(ph, selector, type);
+       if (ret)
+               return ret;
+
+       configs_in_chunk = (max_msg_size - sizeof(*tx)) / (sizeof(__le32) * 2);
+       while (conf_num < nr_configs) {
+               chunk = (nr_configs - conf_num > configs_in_chunk) ?
+                       configs_in_chunk : nr_configs - conf_num;
+
+               ret = ph->xops->xfer_get_init(ph, PINCTRL_SETTINGS_CONFIGURE,
+                                             sizeof(*tx) +
+                                             chunk * 2 * sizeof(__le32), 0, &t);
+               if (ret)
+                       break;
+
+               tx = t->tx.buf;
+               tx->identifier = cpu_to_le32(selector);
+               tx->function_id = cpu_to_le32(0xFFFFFFFF);
+               attributes = FIELD_PREP(GENMASK(1, 0), type) |
+                       FIELD_PREP(GENMASK(9, 2), chunk);
+               tx->attributes = cpu_to_le32(attributes);
+
+               for (i = 0; i < chunk; i++) {
+                       tx->configs[i * 2] =
+                               cpu_to_le32(config_type[conf_num + i]);
+                       tx->configs[i * 2 + 1] =
+                               cpu_to_le32(config_value[conf_num + i]);
+               }
+
+               ret = ph->xops->do_xfer(ph, t);
+
+               ph->xops->xfer_put(ph, t);
+
+               if (ret)
+                       break;
+
+               conf_num += chunk;
+       }
+
+       return ret;
+}
+
+static int scmi_pinctrl_function_select(const struct scmi_protocol_handle *ph,
+                                       u32 group,
+                                       enum scmi_pinctrl_selector_type type,
+                                       u32 function_id)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_settings_conf *tx;
+       u32 attributes;
+
+       ret = scmi_pinctrl_validate_id(ph, group, type);
+       if (ret)
+               return ret;
+
+       ret = ph->xops->xfer_get_init(ph, PINCTRL_SETTINGS_CONFIGURE,
+                                     sizeof(*tx), 0, &t);
+       if (ret)
+               return ret;
+
+       tx = t->tx.buf;
+       tx->identifier = cpu_to_le32(group);
+       tx->function_id = cpu_to_le32(function_id);
+       attributes = FIELD_PREP(GENMASK(1, 0), type) | BIT(10);
+       tx->attributes = cpu_to_le32(attributes);
+
+       ret = ph->xops->do_xfer(ph, t);
+       ph->xops->xfer_put(ph, t);
+
+       return ret;
+}
+
+static int scmi_pinctrl_request_free(const struct scmi_protocol_handle *ph,
+                                    u32 identifier,
+                                    enum scmi_pinctrl_selector_type type,
+                                    enum scmi_pinctrl_protocol_cmd cmd)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_request *tx;
+
+       if (type == FUNCTION_TYPE)
+               return -EINVAL;
+
+       if (cmd != PINCTRL_REQUEST && cmd != PINCTRL_RELEASE)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_validate_id(ph, identifier, type);
+       if (ret)
+               return ret;
+
+       ret = ph->xops->xfer_get_init(ph, cmd, sizeof(*tx), 0, &t);
+       if (ret)
+               return ret;
+
+       tx = t->tx.buf;
+       tx->identifier = cpu_to_le32(identifier);
+       tx->flags = cpu_to_le32(type);
+
+       ret = ph->xops->do_xfer(ph, t);
+       ph->xops->xfer_put(ph, t);
+
+       return ret;
+}
+
+static int scmi_pinctrl_pin_request(const struct scmi_protocol_handle *ph,
+                                   u32 pin)
+{
+       return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_REQUEST);
+}
+
+static int scmi_pinctrl_pin_free(const struct scmi_protocol_handle *ph, u32 pin)
+{
+       return scmi_pinctrl_request_free(ph, pin, PIN_TYPE, PINCTRL_RELEASE);
+}
+
+static int scmi_pinctrl_get_group_info(const struct scmi_protocol_handle *ph,
+                                      u32 selector,
+                                      struct scmi_group_info *group)
+{
+       int ret;
+
+       ret = scmi_pinctrl_attributes(ph, GROUP_TYPE, selector, group->name,
+                                     &group->nr_pins);
+       if (ret)
+               return ret;
+
+       if (!group->nr_pins) {
+               dev_err(ph->dev, "Group %d has 0 elements", selector);
+               return -ENODATA;
+       }
+
+       group->group_pins = kmalloc_array(group->nr_pins,
+                                         sizeof(*group->group_pins),
+                                         GFP_KERNEL);
+       if (!group->group_pins)
+               return -ENOMEM;
+
+       ret = scmi_pinctrl_list_associations(ph, selector, GROUP_TYPE,
+                                            group->nr_pins, group->group_pins);
+       if (ret) {
+               kfree(group->group_pins);
+               return ret;
+       }
+
+       group->present = true;
+       return 0;
+}
+
+static int scmi_pinctrl_get_group_name(const struct scmi_protocol_handle *ph,
+                                      u32 selector, const char **name)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       if (!name)
+               return -EINVAL;
+
+       if (selector >= pi->nr_groups || pi->nr_groups == 0)
+               return -EINVAL;
+
+       if (!pi->groups[selector].present) {
+               int ret;
+
+               ret = scmi_pinctrl_get_group_info(ph, selector,
+                                                 &pi->groups[selector]);
+               if (ret)
+                       return ret;
+       }
+
+       *name = pi->groups[selector].name;
+
+       return 0;
+}
+
+static int scmi_pinctrl_group_pins_get(const struct scmi_protocol_handle *ph,
+                                      u32 selector, const u32 **pins,
+                                      u32 *nr_pins)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       if (!pins || !nr_pins)
+               return -EINVAL;
+
+       if (selector >= pi->nr_groups || pi->nr_groups == 0)
+               return -EINVAL;
+
+       if (!pi->groups[selector].present) {
+               int ret;
+
+               ret = scmi_pinctrl_get_group_info(ph, selector,
+                                                 &pi->groups[selector]);
+               if (ret)
+                       return ret;
+       }
+
+       *pins = pi->groups[selector].group_pins;
+       *nr_pins = pi->groups[selector].nr_pins;
+
+       return 0;
+}
+
+static int scmi_pinctrl_get_function_info(const struct scmi_protocol_handle *ph,
+                                         u32 selector,
+                                         struct scmi_function_info *func)
+{
+       int ret;
+
+       ret = scmi_pinctrl_attributes(ph, FUNCTION_TYPE, selector, func->name,
+                                     &func->nr_groups);
+       if (ret)
+               return ret;
+
+       if (!func->nr_groups) {
+               dev_err(ph->dev, "Function %d has 0 elements", selector);
+               return -ENODATA;
+       }
+
+       func->groups = kmalloc_array(func->nr_groups, sizeof(*func->groups),
+                                    GFP_KERNEL);
+       if (!func->groups)
+               return -ENOMEM;
+
+       ret = scmi_pinctrl_list_associations(ph, selector, FUNCTION_TYPE,
+                                            func->nr_groups, func->groups);
+       if (ret) {
+               kfree(func->groups);
+               return ret;
+       }
+
+       func->present = true;
+       return 0;
+}
+
+static int scmi_pinctrl_get_function_name(const struct scmi_protocol_handle *ph,
+                                         u32 selector, const char **name)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       if (!name)
+               return -EINVAL;
+
+       if (selector >= pi->nr_functions || pi->nr_functions == 0)
+               return -EINVAL;
+
+       if (!pi->functions[selector].present) {
+               int ret;
+
+               ret = scmi_pinctrl_get_function_info(ph, selector,
+                                                    &pi->functions[selector]);
+               if (ret)
+                       return ret;
+       }
+
+       *name = pi->functions[selector].name;
+       return 0;
+}
+
+static int
+scmi_pinctrl_function_groups_get(const struct scmi_protocol_handle *ph,
+                                u32 selector, u32 *nr_groups,
+                                const u32 **groups)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       if (!groups || !nr_groups)
+               return -EINVAL;
+
+       if (selector >= pi->nr_functions || pi->nr_functions == 0)
+               return -EINVAL;
+
+       if (!pi->functions[selector].present) {
+               int ret;
+
+               ret = scmi_pinctrl_get_function_info(ph, selector,
+                                                    &pi->functions[selector]);
+               if (ret)
+                       return ret;
+       }
+
+       *groups = pi->functions[selector].groups;
+       *nr_groups = pi->functions[selector].nr_groups;
+
+       return 0;
+}
+
+static int scmi_pinctrl_mux_set(const struct scmi_protocol_handle *ph,
+                               u32 selector, u32 group)
+{
+       return scmi_pinctrl_function_select(ph, group, GROUP_TYPE, selector);
+}
+
+static int scmi_pinctrl_get_pin_info(const struct scmi_protocol_handle *ph,
+                                    u32 selector, struct scmi_pin_info *pin)
+{
+       int ret;
+
+       if (!pin)
+               return -EINVAL;
+
+       ret = scmi_pinctrl_attributes(ph, PIN_TYPE, selector, pin->name, NULL);
+       if (ret)
+               return ret;
+
+       pin->present = true;
+       return 0;
+}
+
+static int scmi_pinctrl_get_pin_name(const struct scmi_protocol_handle *ph,
+                                    u32 selector, const char **name)
+{
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       if (!name)
+               return -EINVAL;
+
+       if (selector >= pi->nr_pins)
+               return -EINVAL;
+
+       if (!pi->pins[selector].present) {
+               int ret;
+
+               ret = scmi_pinctrl_get_pin_info(ph, selector, &pi->pins[selector]);
+               if (ret)
+                       return ret;
+       }
+
+       *name = pi->pins[selector].name;
+
+       return 0;
+}
+
+static int scmi_pinctrl_name_get(const struct scmi_protocol_handle *ph,
+                                u32 selector,
+                                enum scmi_pinctrl_selector_type type,
+                                const char **name)
+{
+       switch (type) {
+       case PIN_TYPE:
+               return scmi_pinctrl_get_pin_name(ph, selector, name);
+       case GROUP_TYPE:
+               return scmi_pinctrl_get_group_name(ph, selector, name);
+       case FUNCTION_TYPE:
+               return scmi_pinctrl_get_function_name(ph, selector, name);
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct scmi_pinctrl_proto_ops pinctrl_proto_ops = {
+       .count_get = scmi_pinctrl_count_get,
+       .name_get = scmi_pinctrl_name_get,
+       .group_pins_get = scmi_pinctrl_group_pins_get,
+       .function_groups_get = scmi_pinctrl_function_groups_get,
+       .mux_set = scmi_pinctrl_mux_set,
+       .settings_get_one = scmi_pinctrl_settings_get_one,
+       .settings_get_all = scmi_pinctrl_settings_get_all,
+       .settings_conf = scmi_pinctrl_settings_conf,
+       .pin_request = scmi_pinctrl_pin_request,
+       .pin_free = scmi_pinctrl_pin_free,
+};
+
+static int scmi_pinctrl_protocol_init(const struct scmi_protocol_handle *ph)
+{
+       int ret;
+       u32 version;
+       struct scmi_pinctrl_info *pinfo;
+
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
+
+       dev_dbg(ph->dev, "Pinctrl Version %d.%d\n",
+               PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+       pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
+       if (!pinfo)
+               return -ENOMEM;
+
+       ret = scmi_pinctrl_attributes_get(ph, pinfo);
+       if (ret)
+               return ret;
+
+       pinfo->pins = devm_kcalloc(ph->dev, pinfo->nr_pins,
+                                  sizeof(*pinfo->pins), GFP_KERNEL);
+       if (!pinfo->pins)
+               return -ENOMEM;
+
+       pinfo->groups = devm_kcalloc(ph->dev, pinfo->nr_groups,
+                                    sizeof(*pinfo->groups), GFP_KERNEL);
+       if (!pinfo->groups)
+               return -ENOMEM;
+
+       pinfo->functions = devm_kcalloc(ph->dev, pinfo->nr_functions,
+                                       sizeof(*pinfo->functions), GFP_KERNEL);
+       if (!pinfo->functions)
+               return -ENOMEM;
+
+       pinfo->version = version;
+
+       return ph->set_priv(ph, pinfo, version);
+}
+
+static int scmi_pinctrl_protocol_deinit(const struct scmi_protocol_handle *ph)
+{
+       int i;
+       struct scmi_pinctrl_info *pi = ph->get_priv(ph);
+
+       /* Free groups_pins allocated in scmi_pinctrl_get_group_info */
+       for (i = 0; i < pi->nr_groups; i++) {
+               if (pi->groups[i].present) {
+                       kfree(pi->groups[i].group_pins);
+                       pi->groups[i].present = false;
+               }
+       }
+
+       /* Free groups allocated in scmi_pinctrl_get_function_info */
+       for (i = 0; i < pi->nr_functions; i++) {
+               if (pi->functions[i].present) {
+                       kfree(pi->functions[i].groups);
+                       pi->functions[i].present = false;
+               }
+       }
+
+       return 0;
+}
+
+static const struct scmi_protocol scmi_pinctrl = {
+       .id = SCMI_PROTOCOL_PINCTRL,
+       .owner = THIS_MODULE,
+       .instance_init = &scmi_pinctrl_protocol_init,
+       .instance_deinit = &scmi_pinctrl_protocol_deinit,
+       .ops = &pinctrl_proto_ops,
+       .supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
+};
+DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(pinctrl, scmi_pinctrl)
index 317d3fb32676a9197c4a55780d886f223cbbb417..8e95f53bd7b76aec08d78721e3a3b523e82cf68a 100644 (file)
@@ -29,6 +29,8 @@
 #define PROTOCOL_REV_MAJOR(x)  ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x))))
 #define PROTOCOL_REV_MINOR(x)  ((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x))))
 
+#define SCMI_PROTOCOL_VENDOR_BASE      0x80
+
 enum scmi_common_cmd {
        PROTOCOL_VERSION = 0x0,
        PROTOCOL_ATTRIBUTES = 0x1,
@@ -258,6 +260,7 @@ struct scmi_fc_info {
  * @fastchannel_init: A common helper used to initialize FC descriptors by
  *                   gathering FC descriptions from the SCMI platform server.
  * @fastchannel_db_ring: A common helper to ring a FC doorbell.
+ * @get_max_msg_size: A common helper to get the maximum message size.
  */
 struct scmi_proto_helpers_ops {
        int (*extended_name_get)(const struct scmi_protocol_handle *ph,
@@ -277,6 +280,7 @@ struct scmi_proto_helpers_ops {
                                 struct scmi_fc_db_info **p_db,
                                 u32 *rate_limit);
        void (*fastchannel_db_ring)(struct scmi_fc_db_info *db);
+       int (*get_max_msg_size)(const struct scmi_protocol_handle *ph);
 };
 
 /**
@@ -323,6 +327,16 @@ typedef int (*scmi_prot_init_ph_fn_t)(const struct scmi_protocol_handle *);
  *                    protocol by the agent. Each protocol implementation
  *                    in the agent is supposed to downgrade to match the
  *                    protocol version supported by the platform.
+ * @vendor_id: A firmware vendor string for vendor protocols matching.
+ *            Ignored when @id identifies a standard protocol, cannot be NULL
+ *            otherwise.
+ * @sub_vendor_id: A firmware sub_vendor string for vendor protocols matching.
+ *                Ignored if NULL or when @id identifies a standard protocol.
+ * @impl_ver: A firmware implementation version for vendor protocols matching.
+ *           Ignored if zero or if @id identifies a standard protocol.
+ *
+ * Note that vendor protocols matching at load time is performed by attempting
+ * the closest match first against the tuple (vendor, sub_vendor, impl_ver)
  */
 struct scmi_protocol {
        const u8                                id;
@@ -332,6 +346,9 @@ struct scmi_protocol {
        const void                              *ops;
        const struct scmi_protocol_events       *events;
        unsigned int                            supported_version;
+       char                                    *vendor_id;
+       char                                    *sub_vendor_id;
+       u32                                     impl_ver;
 };
 
 #define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(name, proto)  \
@@ -353,6 +370,7 @@ void __exit scmi_##name##_unregister(void)                  \
 DECLARE_SCMI_REGISTER_UNREGISTER(base);
 DECLARE_SCMI_REGISTER_UNREGISTER(clock);
 DECLARE_SCMI_REGISTER_UNREGISTER(perf);
+DECLARE_SCMI_REGISTER_UNREGISTER(pinctrl);
 DECLARE_SCMI_REGISTER_UNREGISTER(power);
 DECLARE_SCMI_REGISTER_UNREGISTER(reset);
 DECLARE_SCMI_REGISTER_UNREGISTER(sensors);
index 5b439d04079c841e1bd698f63d96d1b428f6b2ed..50f6503fe49f5e44474b99a1cc53edf0fa97d283 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/memblock.h>
 #include <linux/spinlock.h>
 #include <linux/crash_dump.h>
+#include <linux/nmi.h>
 #include <asm/unaccepted_memory.h>
 
 /* Protects unaccepted memory bitmap and accepting_list */
@@ -149,6 +150,9 @@ retry:
        }
 
        list_del(&range.list);
+
+       touch_softlockup_watchdog();
+
        spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
 }
 
index fbeeaee4ac85603783412b2afddd9c5ec6fafd49..835a19a7a3a09eee12e2a8280450310c30278838 100644 (file)
@@ -206,10 +206,12 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader)
        if (ret | response->resp_status) {
                dev_warn(priv->dev, "Verification of Upgrade Image failed!\n");
                ret = ret ? ret : -EBADMSG;
+               goto free_message;
        }
 
        dev_info(priv->dev, "Verification of Upgrade Image passed!\n");
 
+free_message:
        devm_kfree(priv->dev, message);
 free_response:
        devm_kfree(priv->dev, response);
@@ -265,7 +267,7 @@ static int mpfs_auto_update_set_image_address(struct mpfs_auto_update_priv *priv
               AUTO_UPDATE_DIRECTORY_WIDTH);
        memset(buffer + AUTO_UPDATE_BLANK_DIRECTORY, 0x0, AUTO_UPDATE_DIRECTORY_WIDTH);
 
-       dev_info(priv->dev, "Writing the image address (%x) to the flash directory (%llx)\n",
+       dev_info(priv->dev, "Writing the image address (0x%x) to the flash directory (0x%llx)\n",
                 image_address, directory_address);
 
        ret = mtd_write(priv->flash, 0x0, erase_size, &bytes_written, (u_char *)buffer);
@@ -313,7 +315,7 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
        erase.len = round_up(size, (size_t)priv->flash->erasesize);
        erase.addr = image_address;
 
-       dev_info(priv->dev, "Erasing the flash at address (%x)\n", image_address);
+       dev_info(priv->dev, "Erasing the flash at address (0x%x)\n", image_address);
        ret = mtd_erase(priv->flash, &erase);
        if (ret)
                goto out;
@@ -323,7 +325,7 @@ static int mpfs_auto_update_write_bitstream(struct fw_upload *fw_uploader, const
         * will do all of that itself - including verifying that the bitstream
         * is valid.
         */
-       dev_info(priv->dev, "Writing the image to the flash at address (%x)\n", image_address);
+       dev_info(priv->dev, "Writing the image to the flash at address (0x%x)\n", image_address);
        ret = mtd_write(priv->flash, (loff_t)image_address, size, &bytes_written, data);
        if (ret)
                goto out;
index 90283f160a2286d8a12b9b0e313f1dfbbbbd9055..68f4df7e6c3c7f2134f6470251d1ad645ce6d74d 100644 (file)
@@ -4,6 +4,8 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
@@ -114,6 +116,10 @@ static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
 #define QCOM_SMC_WAITQ_FLAG_WAKE_ONE   BIT(0)
 #define QCOM_SMC_WAITQ_FLAG_WAKE_ALL   BIT(1)
 
+#define QCOM_DLOAD_MASK                GENMASK(5, 4)
+#define QCOM_DLOAD_NODUMP      0
+#define QCOM_DLOAD_FULLDUMP    1
+
 static const char * const qcom_scm_convention_names[] = {
        [SMC_CONVENTION_UNKNOWN] = "unknown",
        [SMC_CONVENTION_ARM_32] = "smc arm 32",
@@ -163,9 +169,6 @@ static int qcom_scm_bw_enable(void)
        if (!__scm->path)
                return 0;
 
-       if (IS_ERR(__scm->path))
-               return -EINVAL;
-
        mutex_lock(&__scm->scm_bw_lock);
        if (!__scm->scm_vote_count) {
                ret = icc_set_bw(__scm->path, 0, UINT_MAX);
@@ -183,7 +186,7 @@ err_bw:
 
 static void qcom_scm_bw_disable(void)
 {
-       if (IS_ERR_OR_NULL(__scm->path))
+       if (!__scm->path)
                return;
 
        mutex_lock(&__scm->scm_bw_lock);
@@ -496,19 +499,32 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
        return qcom_scm_call_atomic(__scm->dev, &desc, NULL);
 }
 
+static int qcom_scm_io_rmw(phys_addr_t addr, unsigned int mask, unsigned int val)
+{
+       unsigned int old;
+       unsigned int new;
+       int ret;
+
+       ret = qcom_scm_io_readl(addr, &old);
+       if (ret)
+               return ret;
+
+       new = (old & ~mask) | (val & mask);
+
+       return qcom_scm_io_writel(addr, new);
+}
+
 static void qcom_scm_set_download_mode(bool enable)
 {
-       bool avail;
+       u32 val = enable ? QCOM_DLOAD_FULLDUMP : QCOM_DLOAD_NODUMP;
        int ret = 0;
 
-       avail = __qcom_scm_is_call_available(__scm->dev,
-                                            QCOM_SCM_SVC_BOOT,
-                                            QCOM_SCM_BOOT_SET_DLOAD_MODE);
-       if (avail) {
+       if (__scm->dload_mode_addr) {
+               ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK,
+                                     FIELD_PREP(QCOM_DLOAD_MASK, val));
+       } else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT,
+                                               QCOM_SCM_BOOT_SET_DLOAD_MODE)) {
                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");
@@ -557,10 +573,9 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
         */
        mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
                                       GFP_KERNEL);
-       if (!mdata_buf) {
-               dev_err(__scm->dev, "Allocation of metadata buffer failed.\n");
+       if (!mdata_buf)
                return -ENOMEM;
-       }
+
        memcpy(mdata_buf, metadata, size);
 
        ret = qcom_scm_clk_enable();
@@ -569,13 +584,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
 
        ret = qcom_scm_bw_enable();
        if (ret)
-               return ret;
+               goto disable_clk;
 
        desc.args[1] = mdata_phys;
 
        ret = qcom_scm_call(__scm->dev, &desc, &res);
-
        qcom_scm_bw_disable();
+
+disable_clk:
        qcom_scm_clk_disable();
 
 out:
@@ -637,10 +653,12 @@ int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
 
        ret = qcom_scm_bw_enable();
        if (ret)
-               return ret;
+               goto disable_clk;
 
        ret = qcom_scm_call(__scm->dev, &desc, &res);
        qcom_scm_bw_disable();
+
+disable_clk:
        qcom_scm_clk_disable();
 
        return ret ? : res.result[0];
@@ -672,10 +690,12 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral)
 
        ret = qcom_scm_bw_enable();
        if (ret)
-               return ret;
+               goto disable_clk;
 
        ret = qcom_scm_call(__scm->dev, &desc, &res);
        qcom_scm_bw_disable();
+
+disable_clk:
        qcom_scm_clk_disable();
 
        return ret ? : res.result[0];
@@ -706,11 +726,12 @@ int qcom_scm_pas_shutdown(u32 peripheral)
 
        ret = qcom_scm_bw_enable();
        if (ret)
-               return ret;
+               goto disable_clk;
 
        ret = qcom_scm_call(__scm->dev, &desc, &res);
-
        qcom_scm_bw_disable();
+
+disable_clk:
        qcom_scm_clk_disable();
 
        return ret ? : res.result[0];
@@ -1624,8 +1645,10 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
  * We do not yet support re-entrant calls via the qseecom interface. To prevent
  + any potential issues with this, only allow validated machines for now.
  */
-static const struct of_device_id qcom_scm_qseecom_allowlist[] = {
+static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
+       { .compatible = "lenovo,flex-5g" },
        { .compatible = "lenovo,thinkpad-x13s", },
+       { .compatible = "qcom,sc8180x-primus" },
        { }
 };
 
@@ -1713,7 +1736,7 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm)
  */
 bool qcom_scm_is_available(void)
 {
-       return !!__scm;
+       return !!READ_ONCE(__scm);
 }
 EXPORT_SYMBOL_GPL(qcom_scm_is_available);
 
@@ -1744,7 +1767,7 @@ int qcom_scm_wait_for_wq_completion(u32 wq_ctx)
        return 0;
 }
 
-static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int wq_ctx)
+static int qcom_scm_waitq_wakeup(unsigned int wq_ctx)
 {
        int ret;
 
@@ -1776,7 +1799,7 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data)
                        goto out;
                }
 
-               ret = qcom_scm_waitq_wakeup(scm, wq_ctx);
+               ret = qcom_scm_waitq_wakeup(wq_ctx);
                if (ret)
                        goto out;
        } while (more_pending);
@@ -1794,10 +1817,12 @@ static int qcom_scm_probe(struct platform_device *pdev)
        if (!scm)
                return -ENOMEM;
 
+       scm->dev = &pdev->dev;
        ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr);
        if (ret < 0)
                return ret;
 
+       init_completion(&scm->waitq_comp);
        mutex_init(&scm->scm_bw_lock);
 
        scm->path = devm_of_icc_get(&pdev->dev, NULL);
@@ -1829,10 +1854,8 @@ static int qcom_scm_probe(struct platform_device *pdev)
        if (ret)
                return ret;
 
-       __scm = scm;
-       __scm->dev = &pdev->dev;
-
-       init_completion(&__scm->waitq_comp);
+       /* Let all above stores be available after this */
+       smp_store_release(&__scm, scm);
 
        irq = platform_get_irq_optional(pdev, 0);
        if (irq < 0) {
index 322aada20f7421fea3a8d4ca6d95d81a2e897619..ac34876a97f8b046bc177437118b9c94db580cc7 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/kref.h>
 #include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -97,8 +98,8 @@ int rpi_firmware_property_list(struct rpi_firmware *fw,
        if (size & 3)
                return -EINVAL;
 
-       buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr,
-                                GFP_ATOMIC);
+       buf = dma_alloc_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size),
+                                &bus_addr, GFP_ATOMIC);
        if (!buf)
                return -ENOMEM;
 
@@ -126,7 +127,7 @@ int rpi_firmware_property_list(struct rpi_firmware *fw,
                ret = -EINVAL;
        }
 
-       dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr);
+       dma_free_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), buf, bus_addr);
 
        return ret;
 }
index 8b9a2556de16dc5d3d7f0e325f9818b084f47ddb..160968301b1fbc4142c18a10048aaa933e4b9c91 100644 (file)
@@ -87,7 +87,6 @@ struct ti_sci_desc {
  * struct ti_sci_info - Structure representing a TI SCI instance
  * @dev:       Device pointer
  * @desc:      SoC description for this instance
- * @nb:        Reboot Notifier block
  * @d:         Debugfs file entry
  * @debug_region: Memory region where the debug message are available
  * @debug_region_size: Debug region size
@@ -103,7 +102,6 @@ struct ti_sci_desc {
  */
 struct ti_sci_info {
        struct device *dev;
-       struct notifier_block nb;
        const struct ti_sci_desc *desc;
        struct dentry *d;
        void __iomem *debug_region;
@@ -122,7 +120,6 @@ struct ti_sci_info {
 
 #define cl_to_ti_sci_info(c)   container_of(c, struct ti_sci_info, cl)
 #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle)
-#define reboot_to_ti_sci_info(n) container_of(n, struct ti_sci_info, nb)
 
 #ifdef CONFIG_DEBUG_FS
 
@@ -3254,10 +3251,9 @@ devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource);
 
-static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
-                               void *cmd)
+static int tisci_reboot_handler(struct sys_off_data *data)
 {
-       struct ti_sci_info *info = reboot_to_ti_sci_info(nb);
+       struct ti_sci_info *info = data->cb_data;
        const struct ti_sci_handle *handle = &info->handle;
 
        ti_sci_cmd_core_reboot(handle);
@@ -3303,7 +3299,6 @@ static int ti_sci_probe(struct platform_device *pdev)
        struct mbox_client *cl;
        int ret = -EINVAL;
        int i;
-       int reboot = 0;
        u32 h_id;
 
        desc = device_get_match_data(dev);
@@ -3327,8 +3322,6 @@ static int ti_sci_probe(struct platform_device *pdev)
                }
        }
 
-       reboot = of_property_read_bool(dev->of_node,
-                                      "ti,system-reboot-controller");
        INIT_LIST_HEAD(&info->node);
        minfo = &info->minfo;
 
@@ -3399,15 +3392,10 @@ static int ti_sci_probe(struct platform_device *pdev)
 
        ti_sci_setup_ops(info);
 
-       if (reboot) {
-               info->nb.notifier_call = tisci_reboot_handler;
-               info->nb.priority = 128;
-
-               ret = register_restart_handler(&info->nb);
-               if (ret) {
-                       dev_err(dev, "reboot registration fail(%d)\n", ret);
-                       goto out;
-               }
+       ret = devm_register_restart_handler(dev, tisci_reboot_handler, info);
+       if (ret) {
+               dev_err(dev, "reboot registration fail(%d)\n", ret);
+               goto out;
        }
 
        dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n",
index 98b8fd16183e41068cc6108d19a6ef1704ade44e..80cac3a5f97678593ae790b761af661a3149d761 100644 (file)
@@ -78,6 +78,7 @@ static void cci_pci_free_irq(struct pci_dev *pcidev)
 #define PCIE_DEVICE_ID_SILICOM_PAC_N5011       0x1001
 #define PCIE_DEVICE_ID_INTEL_DFL               0xbcce
 /* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
+#define PCIE_SUBDEVICE_ID_INTEL_D5005          0x138d
 #define PCIE_SUBDEVICE_ID_INTEL_N6000          0x1770
 #define PCIE_SUBDEVICE_ID_INTEL_N6001          0x1771
 #define PCIE_SUBDEVICE_ID_INTEL_C6100          0x17d4
@@ -101,6 +102,8 @@ static struct pci_device_id cci_pcie_id_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
        {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
        {PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
+       {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
+                       PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_D5005),},
        {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
                        PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
        {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
index d09c7d72836551ab510031179a9b95340cd3fb36..9dad67ea25974ea4c2dd68d267d728af7603f2bc 100644 (file)
@@ -1193,6 +1193,8 @@ static int edge_detector_update(struct line *line,
                                struct gpio_v2_line_config *lc,
                                unsigned int line_idx, u64 edflags)
 {
+       u64 eflags;
+       int ret;
        u64 active_edflags = READ_ONCE(line->edflags);
        unsigned int debounce_period_us =
                        gpio_v2_line_config_debounce_period(lc, line_idx);
@@ -1204,6 +1206,18 @@ static int edge_detector_update(struct line *line,
        /* sw debounced and still will be...*/
        if (debounce_period_us && READ_ONCE(line->sw_debounced)) {
                line_set_debounce_period(line, debounce_period_us);
+               /*
+                * ensure event fifo is initialised if edge detection
+                * is now enabled.
+                */
+               eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
+               if (eflags && !kfifo_initialized(&line->req->events)) {
+                       ret = kfifo_alloc(&line->req->events,
+                                         line->req->event_buffer_size,
+                                         GFP_KERNEL);
+                       if (ret)
+                               return ret;
+               }
                return 0;
        }
 
@@ -2351,7 +2365,7 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
 
        dflags = READ_ONCE(desc->flags);
 
-       scoped_guard(srcu, &desc->srcu) {
+       scoped_guard(srcu, &desc->gdev->desc_srcu) {
                label = gpiod_get_label(desc);
                if (label && test_bit(FLAG_REQUESTED, &dflags))
                        strscpy(info->consumer, label,
@@ -2799,11 +2813,11 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file)
        struct gpio_chardev_data *cdev = file->private_data;
        struct gpio_device *gdev = cdev->gdev;
 
-       bitmap_free(cdev->watched_lines);
        blocking_notifier_chain_unregister(&gdev->device_notifier,
                                           &cdev->device_unregistered_nb);
        blocking_notifier_chain_unregister(&gdev->line_state_notifier,
                                           &cdev->lineinfo_changed_nb);
+       bitmap_free(cdev->watched_lines);
        gpio_device_put(gdev);
        kfree(cdev);
 
index 94903fc1c1459f9fd26eba62628037492e202620..fa50db0c3605bff72d23058d8c98be0e96e12865 100644 (file)
@@ -101,6 +101,7 @@ static bool gpiolib_initialized;
 
 const char *gpiod_get_label(struct gpio_desc *desc)
 {
+       struct gpio_desc_label *label;
        unsigned long flags;
 
        flags = READ_ONCE(desc->flags);
@@ -108,23 +109,36 @@ const char *gpiod_get_label(struct gpio_desc *desc)
            !test_bit(FLAG_REQUESTED, &flags))
                return "interrupt";
 
-       return test_bit(FLAG_REQUESTED, &flags) ?
-                       srcu_dereference(desc->label, &desc->srcu) : NULL;
+       if (!test_bit(FLAG_REQUESTED, &flags))
+               return NULL;
+
+       label = srcu_dereference_check(desc->label, &desc->gdev->desc_srcu,
+                               srcu_read_lock_held(&desc->gdev->desc_srcu));
+
+       return label->str;
+}
+
+static void desc_free_label(struct rcu_head *rh)
+{
+       kfree(container_of(rh, struct gpio_desc_label, rh));
 }
 
 static int desc_set_label(struct gpio_desc *desc, const char *label)
 {
-       const char *new = NULL, *old;
+       struct gpio_desc_label *new = NULL, *old;
 
        if (label) {
-               new = kstrdup_const(label, GFP_KERNEL);
+               new = kzalloc(struct_size(new, str, strlen(label) + 1),
+                             GFP_KERNEL);
                if (!new)
                        return -ENOMEM;
+
+               strcpy(new->str, label);
        }
 
        old = rcu_replace_pointer(desc->label, new, 1);
-       synchronize_srcu(&desc->srcu);
-       kfree_const(old);
+       if (old)
+               call_srcu(&desc->gdev->desc_srcu, &old->rh, desc_free_label);
 
        return 0;
 }
@@ -695,10 +709,10 @@ EXPORT_SYMBOL_GPL(gpiochip_line_is_valid);
 static void gpiodev_release(struct device *dev)
 {
        struct gpio_device *gdev = to_gpio_device(dev);
-       unsigned int i;
 
-       for (i = 0; i < gdev->ngpio; i++)
-               cleanup_srcu_struct(&gdev->descs[i].srcu);
+       /* Call pending kfree()s for descriptor labels. */
+       synchronize_srcu(&gdev->desc_srcu);
+       cleanup_srcu_struct(&gdev->desc_srcu);
 
        ida_free(&gpio_ida, gdev->id);
        kfree_const(gdev->label);
@@ -975,6 +989,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
        if (ret)
                goto err_remove_from_list;
 
+       ret = init_srcu_struct(&gdev->desc_srcu);
+       if (ret)
+               goto err_cleanup_gdev_srcu;
+
 #ifdef CONFIG_PINCTRL
        INIT_LIST_HEAD(&gdev->pin_ranges);
 #endif
@@ -982,23 +1000,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
        if (gc->names) {
                ret = gpiochip_set_desc_names(gc);
                if (ret)
-                       goto err_cleanup_gdev_srcu;
+                       goto err_cleanup_desc_srcu;
        }
        ret = gpiochip_set_names(gc);
        if (ret)
-               goto err_cleanup_gdev_srcu;
+               goto err_cleanup_desc_srcu;
 
        ret = gpiochip_init_valid_mask(gc);
        if (ret)
-               goto err_cleanup_gdev_srcu;
+               goto err_cleanup_desc_srcu;
 
        for (desc_index = 0; desc_index < gc->ngpio; desc_index++) {
                struct gpio_desc *desc = &gdev->descs[desc_index];
 
-               ret = init_srcu_struct(&desc->srcu);
-               if (ret)
-                       goto err_cleanup_desc_srcu;
-
                if (gc->get_direction && gpiochip_line_is_valid(gc, desc_index)) {
                        assign_bit(FLAG_IS_OUT,
                                   &desc->flags, !gc->get_direction(gc, desc_index));
@@ -1010,7 +1024,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
 
        ret = of_gpiochip_add(gc);
        if (ret)
-               goto err_cleanup_desc_srcu;
+               goto err_free_valid_mask;
 
        ret = gpiochip_add_pin_ranges(gc);
        if (ret)
@@ -1057,10 +1071,10 @@ err_free_hogs:
        gpiochip_remove_pin_ranges(gc);
 err_remove_of_chip:
        of_gpiochip_remove(gc);
-err_cleanup_desc_srcu:
-       while (desc_index--)
-               cleanup_srcu_struct(&gdev->descs[desc_index].srcu);
+err_free_valid_mask:
        gpiochip_free_valid_mask(gc);
+err_cleanup_desc_srcu:
+       cleanup_srcu_struct(&gdev->desc_srcu);
 err_cleanup_gdev_srcu:
        cleanup_srcu_struct(&gdev->srcu);
 err_remove_from_list:
@@ -2390,7 +2404,7 @@ char *gpiochip_dup_line_label(struct gpio_chip *gc, unsigned int offset)
        if (!test_bit(FLAG_REQUESTED, &desc->flags))
                return NULL;
 
-       guard(srcu)(&desc->srcu);
+       guard(srcu)(&desc->gdev->desc_srcu);
 
        label = kstrdup(gpiod_get_label(desc), GFP_KERNEL);
        if (!label)
@@ -4781,7 +4795,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_device *gdev)
        }
 
        for_each_gpio_desc(gc, desc) {
-               guard(srcu)(&desc->srcu);
+               guard(srcu)(&desc->gdev->desc_srcu);
                if (test_bit(FLAG_REQUESTED, &desc->flags)) {
                        gpiod_get_direction(desc);
                        is_out = test_bit(FLAG_IS_OUT, &desc->flags);
index f67d5991ab1c7a58d375b2f6bd3275b41adb8ade..8e0e211ebf0836c12cc4bf29a15245af1880b4fb 100644 (file)
@@ -31,6 +31,7 @@
  * @chip: pointer to the corresponding gpiochip, holding static
  * data for this device
  * @descs: array of ngpio descriptors.
+ * @desc_srcu: ensures consistent state of GPIO descriptors exposed to users
  * @ngpio: the number of GPIO lines on this GPIO device, equal to the size
  * of the @descs array.
  * @can_sleep: indicate whether the GPIO chip driver's callbacks can sleep
@@ -61,6 +62,7 @@ struct gpio_device {
        struct module           *owner;
        struct gpio_chip __rcu  *chip;
        struct gpio_desc        *descs;
+       struct srcu_struct      desc_srcu;
        int                     base;
        u16                     ngpio;
        bool                    can_sleep;
@@ -137,6 +139,11 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
 
 void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action);
 
+struct gpio_desc_label {
+       struct rcu_head rh;
+       char str[];
+};
+
 /**
  * struct gpio_desc - Opaque descriptor for a GPIO
  *
@@ -145,7 +152,6 @@ void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action);
  * @label:             Name of the consumer
  * @name:              Line name
  * @hog:               Pointer to the device node that hogs this line (if any)
- * @srcu:              SRCU struct protecting the label pointer.
  *
  * These are obtained using gpiod_get() and are preferable to the old
  * integer-based handles.
@@ -177,13 +183,12 @@ struct gpio_desc {
 #define FLAG_EVENT_CLOCK_HTE           19 /* GPIO CDEV reports hardware timestamps in events */
 
        /* Connection label */
-       const char __rcu        *label;
+       struct gpio_desc_label __rcu *label;
        /* Name of the GPIO */
        const char              *name;
 #ifdef CONFIG_OF_DYNAMIC
        struct device_node      *hog;
 #endif
-       struct srcu_struct      srcu;
 };
 
 #define gpiod_not_found(desc)          (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
@@ -251,7 +256,7 @@ static inline int gpio_chip_hwgpio(const struct gpio_desc *desc)
 
 #define gpiod_err(desc, fmt, ...) \
 do { \
-       scoped_guard(srcu, &desc->srcu) { \
+       scoped_guard(srcu, &desc->gdev->desc_srcu) { \
                pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), \
                       gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \
        } \
@@ -259,7 +264,7 @@ do { \
 
 #define gpiod_warn(desc, fmt, ...) \
 do { \
-       scoped_guard(srcu, &desc->srcu) { \
+       scoped_guard(srcu, &desc->gdev->desc_srcu) { \
                pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), \
                        gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \
        } \
@@ -267,7 +272,7 @@ do { \
 
 #define gpiod_dbg(desc, fmt, ...) \
 do { \
-       scoped_guard(srcu, &desc->srcu) { \
+       scoped_guard(srcu, &desc->gdev->desc_srcu) { \
                pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), \
                         gpiod_get_label(desc) ? : "?", ##__VA_ARGS__); \
        } \
index 2131de36e3dac00fee06ccbcc1aebe80d69f0fbc..e4d4e55c08ad5a3a11b7133e3f717110c958b09f 100644 (file)
@@ -220,7 +220,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev,
            (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
             kfd_mem_limit.max_ttm_mem_limit) ||
            (adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed >
-            vram_size - reserved_for_pt)) {
+            vram_size - reserved_for_pt - atomic64_read(&adev->vram_pin_size))) {
                ret = -ENOMEM;
                goto release;
        }
index ce733e3cb35d05e445830dc22b8216bd0f6dd014..f6d503432a9ef966b2748acfd801ff04730cad6e 100644 (file)
@@ -1243,14 +1243,18 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
  * amdgpu_bo_move_notify - notification about a memory move
  * @bo: pointer to a buffer object
  * @evict: if this move is evicting the buffer from the graphics address space
+ * @new_mem: new resource for backing the BO
  *
  * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs
  * bookkeeping.
  * TTM driver callback which is called when ttm moves a buffer.
  */
-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
+void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
+                          bool evict,
+                          struct ttm_resource *new_mem)
 {
        struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
+       struct ttm_resource *old_mem = bo->resource;
        struct amdgpu_bo *abo;
 
        if (!amdgpu_bo_is_amdgpu_bo(bo))
@@ -1262,12 +1266,12 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
        amdgpu_bo_kunmap(abo);
 
        if (abo->tbo.base.dma_buf && !abo->tbo.base.import_attach &&
-           bo->resource->mem_type != TTM_PL_SYSTEM)
+           old_mem && old_mem->mem_type != TTM_PL_SYSTEM)
                dma_buf_move_notify(abo->tbo.base.dma_buf);
 
-       /* remember the eviction */
-       if (evict)
-               atomic64_inc(&adev->num_evictions);
+       /* move_notify is called before move happens */
+       trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1,
+                            old_mem ? old_mem->mem_type : -1);
 }
 
 void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
index fa03d9e4874cc65b39e038014ab15fc4e58ba858..bc42ccbde659ac5ef1854b3a90d5561916faf422 100644 (file)
@@ -328,7 +328,9 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,
 int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
                           size_t buffer_size, uint32_t *metadata_size,
                           uint64_t *flags);
-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict);
+void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
+                          bool evict,
+                          struct ttm_resource *new_mem);
 void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);
 vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
 void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
index 1d71729e3f6bcef2c02f9e1ce252dc6cd6461b94..29c197c000187189cc9e5eba93a693e306a74bd3 100644 (file)
@@ -419,7 +419,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
                return false;
 
        if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT ||
-           res->mem_type == AMDGPU_PL_PREEMPT)
+           res->mem_type == AMDGPU_PL_PREEMPT || res->mem_type == AMDGPU_PL_DOORBELL)
                return true;
 
        if (res->mem_type != TTM_PL_VRAM)
@@ -427,7 +427,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
 
        amdgpu_res_first(res, 0, res->size, &cursor);
        while (cursor.remaining) {
-               if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size)
+               if ((cursor.start + cursor.size) > adev->gmc.visible_vram_size)
                        return false;
                amdgpu_res_next(&cursor, cursor.size);
        }
@@ -481,14 +481,16 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
 
        if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
                         bo->ttm == NULL)) {
+               amdgpu_bo_move_notify(bo, evict, new_mem);
                ttm_bo_move_null(bo, new_mem);
-               goto out;
+               return 0;
        }
        if (old_mem->mem_type == TTM_PL_SYSTEM &&
            (new_mem->mem_type == TTM_PL_TT ||
             new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
+               amdgpu_bo_move_notify(bo, evict, new_mem);
                ttm_bo_move_null(bo, new_mem);
-               goto out;
+               return 0;
        }
        if ((old_mem->mem_type == TTM_PL_TT ||
             old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
@@ -498,9 +500,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
                        return r;
 
                amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
+               amdgpu_bo_move_notify(bo, evict, new_mem);
                ttm_resource_free(bo, &bo->resource);
                ttm_bo_assign_mem(bo, new_mem);
-               goto out;
+               return 0;
        }
 
        if (old_mem->mem_type == AMDGPU_PL_GDS ||
@@ -512,8 +515,9 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
            new_mem->mem_type == AMDGPU_PL_OA ||
            new_mem->mem_type == AMDGPU_PL_DOORBELL) {
                /* Nothing to save here */
+               amdgpu_bo_move_notify(bo, evict, new_mem);
                ttm_bo_move_null(bo, new_mem);
-               goto out;
+               return 0;
        }
 
        if (bo->type == ttm_bo_type_device &&
@@ -525,22 +529,23 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
                abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
        }
 
-       if (adev->mman.buffer_funcs_enabled) {
-               if (((old_mem->mem_type == TTM_PL_SYSTEM &&
-                     new_mem->mem_type == TTM_PL_VRAM) ||
-                    (old_mem->mem_type == TTM_PL_VRAM &&
-                     new_mem->mem_type == TTM_PL_SYSTEM))) {
-                       hop->fpfn = 0;
-                       hop->lpfn = 0;
-                       hop->mem_type = TTM_PL_TT;
-                       hop->flags = TTM_PL_FLAG_TEMPORARY;
-                       return -EMULTIHOP;
-               }
+       if (adev->mman.buffer_funcs_enabled &&
+           ((old_mem->mem_type == TTM_PL_SYSTEM &&
+             new_mem->mem_type == TTM_PL_VRAM) ||
+            (old_mem->mem_type == TTM_PL_VRAM &&
+             new_mem->mem_type == TTM_PL_SYSTEM))) {
+               hop->fpfn = 0;
+               hop->lpfn = 0;
+               hop->mem_type = TTM_PL_TT;
+               hop->flags = TTM_PL_FLAG_TEMPORARY;
+               return -EMULTIHOP;
+       }
 
+       amdgpu_bo_move_notify(bo, evict, new_mem);
+       if (adev->mman.buffer_funcs_enabled)
                r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
-       } else {
+       else
                r = -ENODEV;
-       }
 
        if (r) {
                /* Check that all memory is CPU accessible */
@@ -555,11 +560,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
                        return r;
        }
 
-       trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
-out:
-       /* update statistics */
+       /* update statistics after the move */
+       if (evict)
+               atomic64_inc(&adev->num_evictions);
        atomic64_add(bo->base.size, &adev->num_bytes_moved);
-       amdgpu_bo_move_notify(bo, evict);
        return 0;
 }
 
@@ -1559,7 +1563,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
 static void
 amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)
 {
-       amdgpu_bo_move_notify(bo, false);
+       amdgpu_bo_move_notify(bo, false, NULL);
 }
 
 static struct ttm_device_funcs amdgpu_bo_driver = {
index 55aa74cbc5325e23451aa255dd5ce016e0aa4df8..1e6cc0bfc4328d5447922bef89e5d396e91b66b0 100644 (file)
@@ -1139,7 +1139,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
                        goto err_unlock;
                }
                offset = dev->adev->rmmio_remap.bus_addr;
-               if (!offset) {
+               if (!offset || (PAGE_SIZE > 4096)) {
                        err = -ENOMEM;
                        goto err_unlock;
                }
@@ -2307,7 +2307,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
                        return -EINVAL;
                }
                offset = pdd->dev->adev->rmmio_remap.bus_addr;
-               if (!offset) {
+               if (!offset || (PAGE_SIZE > 4096)) {
                        pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
                        return -ENOMEM;
                }
@@ -3349,6 +3349,9 @@ static int kfd_mmio_mmap(struct kfd_node *dev, struct kfd_process *process,
        if (vma->vm_end - vma->vm_start != PAGE_SIZE)
                return -EINVAL;
 
+       if (PAGE_SIZE > 4096)
+               return -EINVAL;
+
        address = dev->adev->rmmio_remap.bus_addr;
 
        vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
index 58c1fe5421934d547bc552d5e72526468951bf69..451bb058cc62039eaf98c0e90487c0884042dfa4 100644 (file)
@@ -829,6 +829,14 @@ struct kfd_process *kfd_create_process(struct task_struct *thread)
        if (process) {
                pr_debug("Process already found\n");
        } else {
+               /* If the process just called exec(3), it is possible that the
+                * cleanup of the kfd_process (following the release of the mm
+                * of the old process image) is still in the cleanup work queue.
+                * Make sure to drain any job before trying to recreate any
+                * resource for this process.
+                */
+               flush_workqueue(kfd_process_wq);
+
                process = create_process(thread);
                if (IS_ERR(process))
                        goto out;
index c51f131eaa2fbc4c5b69e022b3f2648ca8c24e34..bc9eb847ecfe76648f783ff5b7ee67f6dfadd12d 100644 (file)
@@ -1997,9 +1997,8 @@ int kfd_topology_add_device(struct kfd_node *gpu)
                        HSA_CAP_ASIC_REVISION_MASK);
 
        dev->node_props.location_id = pci_dev_id(gpu->adev->pdev);
-       /* On multi-partition nodes, node id = location_id[31:28] */
-       if (gpu->kfd->num_nodes > 1)
-               dev->node_props.location_id |= (dev->gpu->node_id << 28);
+       if (KFD_GC_VERSION(dev->gpu->kfd) == IP_VERSION(9, 4, 3))
+               dev->node_props.location_id |= dev->gpu->node_id;
 
        dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus);
        dev->node_props.max_engine_clk_fcompute =
index f3f94d109726d380326c96e576afd5263e8a1daf..d6e71aa808d881f544053aa2b9c54e5d367cda79 100644 (file)
@@ -4537,15 +4537,18 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
        /* Determine whether to enable Replay support by default. */
        if (!(amdgpu_dc_debug_mask & DC_DISABLE_REPLAY)) {
                switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
-               case IP_VERSION(3, 1, 4):
-               case IP_VERSION(3, 1, 5):
-               case IP_VERSION(3, 1, 6):
-               case IP_VERSION(3, 2, 0):
-               case IP_VERSION(3, 2, 1):
-               case IP_VERSION(3, 5, 0):
-               case IP_VERSION(3, 5, 1):
-                       replay_feature_enabled = true;
-                       break;
+/*
+ * Disabled by default due to https://gitlab.freedesktop.org/drm/amd/-/issues/3344
+ *             case IP_VERSION(3, 1, 4):
+ *             case IP_VERSION(3, 1, 5):
+ *             case IP_VERSION(3, 1, 6):
+ *             case IP_VERSION(3, 2, 0):
+ *             case IP_VERSION(3, 2, 1):
+ *             case IP_VERSION(3, 5, 0):
+ *             case IP_VERSION(3, 5, 1):
+ *                     replay_feature_enabled = true;
+ *                     break;
+ */
                default:
                        replay_feature_enabled = amdgpu_dc_feature_mask & DC_REPLAY_MASK;
                        break;
index eee4945653e2d18d09f8bfc8175251499950f53c..c7715a17f388b34f3c2b9b0c3f2a26916f8bb509 100644 (file)
@@ -1495,7 +1495,9 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -1596,7 +1598,9 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -1681,7 +1685,9 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -1780,7 +1786,9 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -1865,7 +1873,9 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -1964,7 +1974,9 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2045,7 +2057,9 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2141,7 +2155,9 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2220,7 +2236,9 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2276,7 +2294,9 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2347,7 +2367,9 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
@@ -2418,7 +2440,9 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
                if (pipe_ctx->stream &&
-                   pipe_ctx->stream->link == aconnector->dc_link)
+                   pipe_ctx->stream->link == aconnector->dc_link &&
+                   pipe_ctx->stream->sink &&
+                   pipe_ctx->stream->sink == aconnector->dc_sink)
                        break;
        }
 
index 941e96f100f4e5a83ffbcdbe536f3c6f1e49c222..cb31a699c66229513c4c72d12d449ae828551572 100644 (file)
@@ -1219,8 +1219,10 @@ static bool is_dsc_need_re_compute(
        if (dc_link->type != dc_connection_mst_branch)
                return false;
 
-       if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
-               dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+       /* add a check for older MST DSC with no virtual DPCDs */
+       if (needs_dsc_aux_workaround(dc_link)  &&
+               (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
+               dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)))
                return false;
 
        for (i = 0; i < MAX_PIPES; i++)
@@ -1240,7 +1242,15 @@ static bool is_dsc_need_re_compute(
                        continue;
 
                aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
-               if (!aconnector)
+               if (!aconnector || !aconnector->dsc_aux)
+                       continue;
+
+               /*
+                *      check if cached virtual MST DSC caps are available and DSC is supported
+                *      as per specifications in their Virtual DPCD registers.
+               */
+               if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported ||
+                       aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
                        continue;
 
                stream_on_link[new_stream_on_link_num] = aconnector;
index 05f392501c0ae3572250061b31defef7cde51fb5..ab31643b109698ec95a11da1aabdfa258705989a 100644 (file)
@@ -2948,6 +2948,7 @@ static enum bp_result construct_integrated_info(
                                result = get_integrated_info_v2_1(bp, info);
                                break;
                        case 2:
+                       case 3:
                                result = get_integrated_info_v2_2(bp, info);
                                break;
                        default:
index 644da463732093f9d3798b3de9565b5f7fd9ea0b..5506cf9b3672f80992c846b8686613427976bb81 100644 (file)
@@ -145,6 +145,10 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
         */
        clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
        if (safe_to_lower) {
+               if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
+                       dcn315_smu_set_dtbclk(clk_mgr, false);
+                       clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+               }
                /* check that we're not already in lower */
                if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
                        display_count = dcn315_get_active_display_cnt_wa(dc, context);
@@ -160,6 +164,10 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
                        }
                }
        } else {
+               if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
+                       dcn315_smu_set_dtbclk(clk_mgr, true);
+                       clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+               }
                /* check that we're not already in D0 */
                if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
                        union display_idle_optimization_u idle_info = { 0 };
index bec252e1dd27a98263b5bd3299cc3dfd8ed089e9..e506e4f969ca9ffc90bdf8714c936a72aa9c2b17 100644 (file)
@@ -712,8 +712,12 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
                                         * since we calculate mode support based on softmax being the max UCLK
                                         * frequency.
                                         */
-                                       dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
-                                                       dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
+                                       if (dc->debug.disable_dc_mode_overwrite) {
+                                               dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
+                                               dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
+                                       } else
+                                               dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+                                                               dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
                                } else {
                                        dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
                                }
@@ -746,8 +750,13 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
                /* set UCLK to requested value if P-State switching is supported, or to re-enable P-State switching */
                if (clk_mgr_base->clks.p_state_change_support &&
                                (update_uclk || !clk_mgr_base->clks.prev_p_state_change_support) &&
-                               !dc->work_arounds.clock_update_disable_mask.uclk)
+                               !dc->work_arounds.clock_update_disable_mask.uclk) {
+                       if (dc->clk_mgr->dc_mode_softmax_enabled && dc->debug.disable_dc_mode_overwrite)
+                               dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
+                                               max((int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz)));
+
                        dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
+               }
 
                if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
                                clk_mgr_base->clks.num_ways > new_clocks->num_ways) {
index 03b554e912a20d4ae58e5161d55943eb0bb7a0d9..d68c83e40d4d6c3bd89e66cc5ecc63ca14c010d0 100644 (file)
@@ -1801,6 +1801,9 @@ bool dc_validate_boot_timing(const struct dc *dc,
                return false;
        }
 
+       if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)
+               return false;
+
        if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) {
                DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
                return false;
index 5b7ad38f85e08f422c32e48bdb4b384b8bb75e08..65e45a0b4ff34351013a6e7f5debe0eb8c676e8d 100644 (file)
@@ -395,6 +395,12 @@ void dcn31_hpo_dp_link_enc_set_throttled_vcp_size(
                                x),
                        25));
 
+       // If y rounds up to integer, carry it over to x.
+       if (y >> 25) {
+               x += 1;
+               y = 0;
+       }
+
        switch (stream_encoder_inst) {
        case 0:
                REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0,
index deb6d162a2d5c00df00b069a57e885b34a18e939..7307b7b8d8ad7595bcfbf09e0a39786df389398f 100644 (file)
@@ -291,6 +291,7 @@ static struct _vcs_dpi_soc_bounding_box_st dcn3_15_soc = {
        .do_urgent_latency_adjustment = false,
        .urgent_latency_adjustment_fabric_clock_component_us = 0,
        .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+       .dispclk_dppclk_vco_speed_mhz = 2400.0,
        .num_chans = 4,
        .dummy_pstate_latency_us = 10.0
 };
@@ -438,6 +439,7 @@ static struct _vcs_dpi_soc_bounding_box_st dcn3_16_soc = {
        .do_urgent_latency_adjustment = false,
        .urgent_latency_adjustment_fabric_clock_component_us = 0,
        .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+       .dispclk_dppclk_vco_speed_mhz = 2500.0,
 };
 
 void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
index 21e0eef3269b10fab97ac3cb7e44cf54f33c775d..53e40d3c48d4bcba6136f5e27ef1019c1fdcfbd1 100644 (file)
@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
        .dcn_downspread_percent = 0.5,
        .gpuvm_min_page_size_bytes = 4096,
        .hostvm_min_page_size_bytes = 4096,
-       .do_urgent_latency_adjustment = 0,
+       .do_urgent_latency_adjustment = 1,
        .urgent_latency_adjustment_fabric_clock_component_us = 0,
-       .urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+       .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
 };
 
 void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
index a5560b3fc39ba9b432e0e5605b3972810de38933..9067ca78f8511145e8c2e88789d38f0f71505abf 100644 (file)
@@ -638,22 +638,43 @@ void dcn35_power_down_on_boot(struct dc *dc)
 
 bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
-       struct dc_link *edp_links[MAX_NUM_EDP];
-       int i, edp_num;
        if (dc->debug.dmcub_emulation)
                return true;
 
        if (enable) {
-               dc_get_edp_links(dc, edp_links, &edp_num);
-               if (edp_num == 0 || edp_num > 1)
-                       return false;
+               uint32_t num_active_edp = 0;
+               int i;
 
                for (i = 0; i < dc->current_state->stream_count; ++i) {
                        struct dc_stream_state *stream = dc->current_state->streams[i];
+                       struct dc_link *link = stream->link;
+                       bool is_psr = link && !link->panel_config.psr.disable_psr &&
+                                     (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
+                                      link->psr_settings.psr_version == DC_PSR_VERSION_SU_1);
+                       bool is_replay = link && link->replay_settings.replay_feature_enabled;
+
+                       /* Ignore streams that disabled. */
+                       if (stream->dpms_off)
+                               continue;
+
+                       /* Active external displays block idle optimizations. */
+                       if (!dc_is_embedded_signal(stream->signal))
+                               return false;
+
+                       /* If not PWRSEQ0 can't enter idle optimizations */
+                       if (link && link->link_index != 0)
+                               return false;
 
-                       if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal))
+                       /* Check for panel power features required for idle optimizations. */
+                       if (!is_psr && !is_replay)
                                return false;
+
+                       num_active_edp += 1;
                }
+
+               /* If more than one active eDP then disallow. */
+               if (num_active_edp > 1)
+                       return false;
        }
 
        // TODO: review other cases when idle optimization is allowed
index 5491b707cec881b9854ab96834503c1e88053380..5a965c26bf2095fa44c5f81e89c0feded2b99b38 100644 (file)
@@ -270,7 +270,7 @@ static void set_usb4_req_bw_req(struct dc_link *link, int req_bw)
 
        /* Error check whether requested and allocated are equal */
        req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity);
-       if (req_bw == link->dpia_bw_alloc_config.allocated_bw) {
+       if (req_bw && (req_bw == link->dpia_bw_alloc_config.allocated_bw)) {
                DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n",
                        __func__, link->link_index);
        }
@@ -341,6 +341,14 @@ bool link_dp_dpia_set_dptx_usb4_bw_alloc_support(struct dc_link *link)
                        ret = true;
                        init_usb4_bw_struct(link);
                        link->dpia_bw_alloc_config.bw_alloc_enabled = true;
+
+                       /*
+                        * During DP tunnel creation, CM preallocates BW and reduces estimated BW of other
+                        * DPIA. CM release preallocation only when allocation is complete. Do zero alloc
+                        * to make the CM to release preallocation and update estimated BW correctly for
+                        * all DPIAs per host router
+                        */
+                       link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, 0);
                }
        }
 
index a2387cea1af9a184124121b3d631740e01c41484..622214b365a25aa50fc21a6dde5b7e6f192a55b7 100644 (file)
@@ -2449,6 +2449,7 @@ static bool dcn20_resource_construct(
        dc->caps.post_blend_color_processing = true;
        dc->caps.force_dp_tps4_for_cp2520 = true;
        dc->caps.extended_aux_timeout_support = true;
+       dc->caps.dmcub_support = true;
 
        /* Color pipeline capabilities */
        dc->caps.color.dpp.dcn_arch = 1;
index 949131bd1ecb215c960b7aabb9ad690da715d90c..4abfcd32747d3a6fef57d7089cc9a97ea70290bb 100644 (file)
@@ -226,7 +226,7 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
        struct amdgpu_device *adev = smu->adev;
        int ret = 0;
 
-       if (!en && !adev->in_s0ix) {
+       if (!en && adev->in_s4) {
                /* Adds a GFX reset as workaround just before sending the
                 * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
                 * an invalid state.
index b0516505f7ae928ad39c7a383264507f6efd7531..4d2df7f64dc51fbb66fbfeb598e3f115ef3cc368 100644 (file)
@@ -2940,7 +2940,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
                                                     dev->mode_config.max_width,
                                                     dev->mode_config.max_height);
                else
-                       drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe",
+                       drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n",
                                    connector->base.id, connector->name);
        }
 
index 07e0c73204f309e510d69406d3ccf01951e99848..ed81e1466c4b5ae1791dfa0b0462ed3ae5aec95d 100644 (file)
@@ -76,19 +76,6 @@ struct intel_audio_funcs {
                                       struct intel_crtc_state *crtc_state);
 };
 
-/* DP N/M table */
-#define LC_810M        810000
-#define LC_540M        540000
-#define LC_270M        270000
-#define LC_162M        162000
-
-struct dp_aud_n_m {
-       int sample_rate;
-       int clock;
-       u16 m;
-       u16 n;
-};
-
 struct hdmi_aud_ncts {
        int sample_rate;
        int clock;
@@ -96,60 +83,6 @@ struct hdmi_aud_ncts {
        int cts;
 };
 
-/* Values according to DP 1.4 Table 2-104 */
-static const struct dp_aud_n_m dp_aud_n_m[] = {
-       { 32000, LC_162M, 1024, 10125 },
-       { 44100, LC_162M, 784, 5625 },
-       { 48000, LC_162M, 512, 3375 },
-       { 64000, LC_162M, 2048, 10125 },
-       { 88200, LC_162M, 1568, 5625 },
-       { 96000, LC_162M, 1024, 3375 },
-       { 128000, LC_162M, 4096, 10125 },
-       { 176400, LC_162M, 3136, 5625 },
-       { 192000, LC_162M, 2048, 3375 },
-       { 32000, LC_270M, 1024, 16875 },
-       { 44100, LC_270M, 784, 9375 },
-       { 48000, LC_270M, 512, 5625 },
-       { 64000, LC_270M, 2048, 16875 },
-       { 88200, LC_270M, 1568, 9375 },
-       { 96000, LC_270M, 1024, 5625 },
-       { 128000, LC_270M, 4096, 16875 },
-       { 176400, LC_270M, 3136, 9375 },
-       { 192000, LC_270M, 2048, 5625 },
-       { 32000, LC_540M, 1024, 33750 },
-       { 44100, LC_540M, 784, 18750 },
-       { 48000, LC_540M, 512, 11250 },
-       { 64000, LC_540M, 2048, 33750 },
-       { 88200, LC_540M, 1568, 18750 },
-       { 96000, LC_540M, 1024, 11250 },
-       { 128000, LC_540M, 4096, 33750 },
-       { 176400, LC_540M, 3136, 18750 },
-       { 192000, LC_540M, 2048, 11250 },
-       { 32000, LC_810M, 1024, 50625 },
-       { 44100, LC_810M, 784, 28125 },
-       { 48000, LC_810M, 512, 16875 },
-       { 64000, LC_810M, 2048, 50625 },
-       { 88200, LC_810M, 1568, 28125 },
-       { 96000, LC_810M, 1024, 16875 },
-       { 128000, LC_810M, 4096, 50625 },
-       { 176400, LC_810M, 3136, 28125 },
-       { 192000, LC_810M, 2048, 16875 },
-};
-
-static const struct dp_aud_n_m *
-audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) {
-               if (rate == dp_aud_n_m[i].sample_rate &&
-                   crtc_state->port_clock == dp_aud_n_m[i].clock)
-                       return &dp_aud_n_m[i];
-       }
-
-       return NULL;
-}
-
 static const struct {
        int clock;
        u32 config;
@@ -387,47 +320,17 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
                           const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-       struct i915_audio_component *acomp = i915->display.audio.component;
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-       enum port port = encoder->port;
-       const struct dp_aud_n_m *nm;
-       int rate;
-       u32 tmp;
-
-       rate = acomp ? acomp->aud_sample_rate[port] : 0;
-       nm = audio_config_dp_get_n_m(crtc_state, rate);
-       if (nm)
-               drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m,
-                           nm->n);
-       else
-               drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n");
-
-       tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
-       tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
-       tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
-       tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
-       tmp |= AUD_CONFIG_N_VALUE_INDEX;
 
-       if (nm) {
-               tmp &= ~AUD_CONFIG_N_MASK;
-               tmp |= AUD_CONFIG_N(nm->n);
-               tmp |= AUD_CONFIG_N_PROG_ENABLE;
-       }
-
-       intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
-
-       tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
-       tmp &= ~AUD_CONFIG_M_MASK;
-       tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
-       tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
-
-       if (nm) {
-               tmp |= nm->m;
-               tmp |= AUD_M_CTS_M_VALUE_INDEX;
-               tmp |= AUD_M_CTS_M_PROG_ENABLE;
-       }
+       /* Enable time stamps. Let HW calculate Maud/Naud values */
+       intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
+                    AUD_CONFIG_N_VALUE_INDEX |
+                    AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
+                    AUD_CONFIG_UPPER_N_MASK |
+                    AUD_CONFIG_LOWER_N_MASK |
+                    AUD_CONFIG_N_PROG_ENABLE,
+                    AUD_CONFIG_N_VALUE_INDEX);
 
-       intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
 }
 
 static void
index 52bd3576835b6ba15b31d8e17a94e9b65f612b1c..7d1e443f97b93e77b47746ce89492104e0826df5 100644 (file)
@@ -1042,22 +1042,11 @@ parse_lfp_backlight(struct drm_i915_private *i915,
        panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
        panel->vbt.backlight.controller = 0;
        if (i915->display.vbt.version >= 191) {
-               size_t exp_size;
+               const struct lfp_backlight_control_method *method;
 
-               if (i915->display.vbt.version >= 236)
-                       exp_size = sizeof(struct bdb_lfp_backlight_data);
-               else if (i915->display.vbt.version >= 234)
-                       exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
-               else
-                       exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
-
-               if (get_blocksize(backlight_data) >= exp_size) {
-                       const struct lfp_backlight_control_method *method;
-
-                       method = &backlight_data->backlight_control[panel_type];
-                       panel->vbt.backlight.type = method->type;
-                       panel->vbt.backlight.controller = method->controller;
-               }
+               method = &backlight_data->backlight_control[panel_type];
+               panel->vbt.backlight.type = method->type;
+               panel->vbt.backlight.controller = method->controller;
        }
 
        panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
index a9f44abfc9fc283da886724d9d2447c4b8ad59f4..b50cd0dcabda90ab228578d25e6dbd2219380e28 100644 (file)
@@ -897,11 +897,6 @@ struct lfp_brightness_level {
        u16 reserved;
 } __packed;
 
-#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
-       offsetof(struct bdb_lfp_backlight_data, brightness_level)
-#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
-       offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
-
 struct bdb_lfp_backlight_data {
        u8 entry_size;
        struct lfp_backlight_data_entry data[16];
index 044219c5960a5385b7c07b3ded67bc3c48db6330..99b71bb7da0a6bb8a1f905ab71fcdadf61037e78 100644 (file)
@@ -8,14 +8,14 @@
 #include "intel_gt_ccs_mode.h"
 #include "intel_gt_regs.h"
 
-void intel_gt_apply_ccs_mode(struct intel_gt *gt)
+unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt)
 {
        int cslice;
        u32 mode = 0;
        int first_ccs = __ffs(CCS_MASK(gt));
 
        if (!IS_DG2(gt->i915))
-               return;
+               return 0;
 
        /* Build the value for the fixed CCS load balancing */
        for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
@@ -35,5 +35,5 @@ void intel_gt_apply_ccs_mode(struct intel_gt *gt)
                                                     XEHP_CCS_MODE_CSLICE_MASK);
        }
 
-       intel_uncore_write(gt->uncore, XEHP_CCS_MODE, mode);
+       return mode;
 }
index 9e5549caeb269328c2f2a33a783b257dec3e5a8d..55547f2ff426a46040842617d34a50339b03d737 100644 (file)
@@ -8,6 +8,6 @@
 
 struct intel_gt;
 
-void intel_gt_apply_ccs_mode(struct intel_gt *gt);
+unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt);
 
 #endif /* __INTEL_GT_CCS_MODE_H__ */
index 6ec3582c97357780f823865cf0a9a9581b50d288..85c860ea9d7c2288983e417c1c258c309d4b599b 100644 (file)
@@ -2859,6 +2859,7 @@ add_render_compute_tuning_settings(struct intel_gt *gt,
 static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
 {
        struct intel_gt *gt = engine->gt;
+       u32 mode;
 
        if (!IS_DG2(gt->i915))
                return;
@@ -2875,7 +2876,8 @@ static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_li
         * After having disabled automatic load balancing we need to
         * assign all slices to a single CCS. We will call it CCS mode 1
         */
-       intel_gt_apply_ccs_mode(gt);
+       mode = intel_gt_apply_ccs_mode(gt);
+       wa_masked_en(wal, XEHP_CCS_MODE, mode);
 }
 
 /*
index 408dbe63a90cfd5c5a5b51aa80fdd8bf7aaadde5..a0c5c41c8aa24a454c7c6ec10529ef8062ee3e9d 100644 (file)
@@ -7,13 +7,14 @@
 #include "pvr_rogue_mips.h"
 
 #include <asm/page.h>
+#include <linux/math.h>
 #include <linux/types.h>
 
 /* Forward declaration from pvr_gem.h. */
 struct pvr_gem_object;
 
-#define PVR_MIPS_PT_PAGE_COUNT ((ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K) \
-                               >> PAGE_SHIFT)
+#define PVR_MIPS_PT_PAGE_COUNT DIV_ROUND_UP(ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K, PAGE_SIZE)
+
 /**
  * struct pvr_fw_mips_data - MIPS-specific data
  */
index 5a9538bc0e26f83468a4e3fb751c0ee64643fbc6..5565f7777529f8c092fe731add79270971e3bc3d 100644 (file)
 #define HHI_HDMI_CLK_CNTL      0x1cc /* 0x73 */
 #define HHI_HDMI_PHY_CNTL0     0x3a0 /* 0xe8 */
 #define HHI_HDMI_PHY_CNTL1     0x3a4 /* 0xe9 */
+#define  PHY_CNTL1_INIT                0x03900000
+#define  PHY_INVERT            BIT(17)
 #define HHI_HDMI_PHY_CNTL2     0x3a8 /* 0xea */
 #define HHI_HDMI_PHY_CNTL3     0x3ac /* 0xeb */
 #define HHI_HDMI_PHY_CNTL4     0x3b0 /* 0xec */
@@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
                                    unsigned int addr);
        void            (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
                                     unsigned int addr, unsigned int data);
+       u32 cntl0_init;
+       u32 cntl1_init;
 };
 
 struct meson_dw_hdmi {
@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
            dw_hdmi_bus_fmt_is_420(hdmi))
                mode_is_420 = true;
 
-       /* Enable clocks */
-       regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
-
-       /* Bring HDMITX MEM output of power down */
-       regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
-
-       /* Bring out of reset */
-       dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET,  0);
-
-       /* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
-       dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
-                              0x3, 0x3);
-
-       /* Enable cec_clk and hdcp22_tmdsclk_en */
-       dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
-                              0x3 << 4, 0x3 << 4);
-
-       /* Enable normal output to PHY */
-       dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
-
        /* TMDS pattern setup */
        if (mode->clock > 340000 && !mode_is_420) {
                dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
@@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
        /* Setup PHY parameters */
        meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420);
 
-       /* Setup PHY */
-       regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-                          0xffff << 16, 0x0390 << 16);
-
-       /* BIT_INVERT */
-       if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
-           dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
-           dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
-               regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-                                  BIT(17), 0);
-       else
-               regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-                                  BIT(17), BIT(17));
-
        /* Disable clock, fifo, fifo_wr */
        regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
 
@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
 
        DRM_DEBUG_DRIVER("\n");
 
-       regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
+       /* Fallback to init mode */
+       regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init);
+       regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init);
 }
 
 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
@@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
        .fast_io = true,
 };
 
-static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
        .top_read = dw_hdmi_top_read,
        .top_write = dw_hdmi_top_write,
        .dwc_read = dw_hdmi_dwc_read,
        .dwc_write = dw_hdmi_dwc_write,
+       .cntl0_init = 0x0,
+       .cntl1_init = PHY_CNTL1_INIT | PHY_INVERT,
+};
+
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
+       .top_read = dw_hdmi_top_read,
+       .top_write = dw_hdmi_top_write,
+       .dwc_read = dw_hdmi_dwc_read,
+       .dwc_write = dw_hdmi_dwc_write,
+       .cntl0_init = 0x0,
+       .cntl1_init = PHY_CNTL1_INIT,
 };
 
 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
@@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
        .top_write = dw_hdmi_g12a_top_write,
        .dwc_read = dw_hdmi_g12a_dwc_read,
        .dwc_write = dw_hdmi_g12a_dwc_write,
+       .cntl0_init = 0x000b4242, /* Bandgap */
+       .cntl1_init = PHY_CNTL1_INIT,
 };
 
 static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
@@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
        meson_dw_hdmi->data->top_write(meson_dw_hdmi,
                                       HDMITX_TOP_CLK_CNTL, 0xff);
 
+       /* Enable normal output to PHY */
+       meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
+
+       /* Setup PHY */
+       regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init);
+       regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init);
+
        /* Enable HDMI-TX Interrupt */
        meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
                                       HDMITX_TOP_INTR_CORE);
@@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
 
 static const struct of_device_id meson_dw_hdmi_of_table[] = {
        { .compatible = "amlogic,meson-gxbb-dw-hdmi",
-         .data = &meson_dw_hdmi_gx_data },
+         .data = &meson_dw_hdmi_gxbb_data },
        { .compatible = "amlogic,meson-gxl-dw-hdmi",
-         .data = &meson_dw_hdmi_gx_data },
+         .data = &meson_dw_hdmi_gxl_data },
        { .compatible = "amlogic,meson-gxm-dw-hdmi",
-         .data = &meson_dw_hdmi_gx_data },
+         .data = &meson_dw_hdmi_gxl_data },
        { .compatible = "amlogic,meson-g12a-dw-hdmi",
          .data = &meson_dw_hdmi_g12a_data },
        { }
index 6f5d376d8fcc1ecb6d9faa80b4b06ba4cd1b21e4..a11d16a16c3b25d288c07bba8ce4f545b3bda32d 100644 (file)
@@ -15,7 +15,9 @@ struct nvkm_gsp_mem {
 };
 
 struct nvkm_gsp_radix3 {
-       struct nvkm_gsp_mem mem[3];
+       struct nvkm_gsp_mem lvl0;
+       struct nvkm_gsp_mem lvl1;
+       struct sg_table lvl2;
 };
 
 int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *);
index 9858c1438aa7feda7d84ff5442f611b23f101b2d..abe41f7a34045531e90ca98b74ab03aedf5538c5 100644 (file)
@@ -1624,7 +1624,7 @@ r535_gsp_wpr_meta_init(struct nvkm_gsp *gsp)
        meta->magic = GSP_FW_WPR_META_MAGIC;
        meta->revision = GSP_FW_WPR_META_REVISION;
 
-       meta->sysmemAddrOfRadix3Elf = gsp->radix3.mem[0].addr;
+       meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr;
        meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size;
 
        meta->sysmemAddrOfBootloader = gsp->boot.fw.addr;
@@ -1919,8 +1919,9 @@ nvkm_gsp_sg(struct nvkm_device *device, u64 size, struct sg_table *sgt)
 static void
 nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3)
 {
-       for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--)
-               nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]);
+       nvkm_gsp_sg_free(gsp->subdev.device, &rx3->lvl2);
+       nvkm_gsp_mem_dtor(gsp, &rx3->lvl1);
+       nvkm_gsp_mem_dtor(gsp, &rx3->lvl0);
 }
 
 /**
@@ -1960,36 +1961,60 @@ static int
 nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size,
                   struct nvkm_gsp_radix3 *rx3)
 {
-       u64 addr;
+       struct sg_dma_page_iter sg_dma_iter;
+       struct scatterlist *sg;
+       size_t bufsize;
+       u64 *pte;
+       int ret, i, page_idx = 0;
 
-       for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) {
-               u64 *ptes;
-               size_t bufsize;
-               int ret, idx;
+       ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl0);
+       if (ret)
+               return ret;
 
-               bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE);
-               ret = nvkm_gsp_mem_ctor(gsp, bufsize, &rx3->mem[i]);
-               if (ret)
-                       return ret;
+       ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl1);
+       if (ret)
+               goto lvl1_fail;
 
-               ptes = rx3->mem[i].data;
-               if (i == 2) {
-                       struct scatterlist *sgl;
+       // Allocate level 2
+       bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE);
+       ret = nvkm_gsp_sg(gsp->subdev.device, bufsize, &rx3->lvl2);
+       if (ret)
+               goto lvl2_fail;
 
-                       for_each_sgtable_dma_sg(sgt, sgl, idx) {
-                               for (int j = 0; j < sg_dma_len(sgl) / GSP_PAGE_SIZE; j++)
-                                       *ptes++ = sg_dma_address(sgl) + (GSP_PAGE_SIZE * j);
-                       }
-               } else {
-                       for (int j = 0; j < size / GSP_PAGE_SIZE; j++)
-                               *ptes++ = addr + GSP_PAGE_SIZE * j;
+       // Write the bus address of level 1 to level 0
+       pte = rx3->lvl0.data;
+       *pte = rx3->lvl1.addr;
+
+       // Write the bus address of each page in level 2 to level 1
+       pte = rx3->lvl1.data;
+       for_each_sgtable_dma_page(&rx3->lvl2, &sg_dma_iter, 0)
+               *pte++ = sg_page_iter_dma_address(&sg_dma_iter);
+
+       // Finally, write the bus address of each page in sgt to level 2
+       for_each_sgtable_sg(&rx3->lvl2, sg, i) {
+               void *sgl_end;
+
+               pte = sg_virt(sg);
+               sgl_end = (void *)pte + sg->length;
+
+               for_each_sgtable_dma_page(sgt, &sg_dma_iter, page_idx) {
+                       *pte++ = sg_page_iter_dma_address(&sg_dma_iter);
+                       page_idx++;
+
+                       // Go to the next scatterlist for level 2 if we've reached the end
+                       if ((void *)pte >= sgl_end)
+                               break;
                }
+       }
 
-               size = rx3->mem[i].size;
-               addr = rx3->mem[i].addr;
+       if (ret) {
+lvl2_fail:
+               nvkm_gsp_mem_dtor(gsp, &rx3->lvl1);
+lvl1_fail:
+               nvkm_gsp_mem_dtor(gsp, &rx3->lvl0);
        }
 
-       return 0;
+       return ret;
 }
 
 int
@@ -2021,7 +2046,7 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend)
                sr = gsp->sr.meta.data;
                sr->magic = GSP_FW_SR_META_MAGIC;
                sr->revision = GSP_FW_SR_META_REVISION;
-               sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.mem[0].addr;
+               sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr;
                sr->sizeOfSuspendResumeData = len;
 
                mbox0 = lower_32_bits(gsp->sr.meta.addr);
index d037b3b8b9993458a8f1615902363a6663a94052..5b15d0294836756a1e3cfced716b86cd4e093e76 100644 (file)
@@ -177,7 +177,7 @@ config DRM_PANEL_ILITEK_IL9322
 
 config DRM_PANEL_ILITEK_ILI9341
        tristate "Ilitek ILI9341 240x320 QVGA panels"
-       depends on OF && SPI
+       depends on SPI
        select DRM_KMS_HELPER
        select DRM_GEM_DMA_HELPER
        depends on BACKLIGHT_CLASS_DEVICE
index 3574681891e816f5f32a012814e22f7335f687d2..b933380b7eb783fad1d1101b61d7a630ade11315 100644 (file)
@@ -22,8 +22,9 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
@@ -421,7 +422,7 @@ static int ili9341_dpi_prepare(struct drm_panel *panel)
 
        ili9341_dpi_init(ili);
 
-       return ret;
+       return 0;
 }
 
 static int ili9341_dpi_enable(struct drm_panel *panel)
@@ -691,7 +692,7 @@ static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc,
         * Every new incarnation of this display must have a unique
         * data entry for the system in this driver.
         */
-       ili->conf = of_device_get_match_data(dev);
+       ili->conf = device_get_match_data(dev);
        if (!ili->conf) {
                dev_err(dev, "missing device configuration\n");
                return -ENODEV;
@@ -714,18 +715,18 @@ static int ili9341_probe(struct spi_device *spi)
 
        reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
        if (IS_ERR(reset))
-               dev_err(dev, "Failed to get gpio 'reset'\n");
+               return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n");
 
        dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
        if (IS_ERR(dc))
-               dev_err(dev, "Failed to get gpio 'dc'\n");
+               return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n");
 
        if (!strcmp(id->name, "sf-tc240t-9370-t"))
                return ili9341_dpi_probe(spi, dc, reset);
        else if (!strcmp(id->name, "yx240qv29"))
                return ili9341_dbi_probe(spi, dc, reset);
 
-       return -1;
+       return -ENODEV;
 }
 
 static void ili9341_remove(struct spi_device *spi)
index 9febc8b73f09efaaaac9d6fb8d2776f2148aed89..368d26da0d6a233467cdc8ef5820ebf4b7ddb964 100644 (file)
@@ -58,56 +58,16 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr,
                           signed long timeout)
 {
        struct qxl_device *qdev;
-       struct qxl_release *release;
-       int count = 0, sc = 0;
-       bool have_drawable_releases;
        unsigned long cur, end = jiffies + timeout;
 
        qdev = container_of(fence->lock, struct qxl_device, release_lock);
-       release = container_of(fence, struct qxl_release, base);
-       have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE;
-
-retry:
-       sc++;
-
-       if (dma_fence_is_signaled(fence))
-               goto signaled;
-
-       qxl_io_notify_oom(qdev);
-
-       for (count = 0; count < 11; count++) {
-               if (!qxl_queue_garbage_collect(qdev, true))
-                       break;
-
-               if (dma_fence_is_signaled(fence))
-                       goto signaled;
-       }
-
-       if (dma_fence_is_signaled(fence))
-               goto signaled;
 
-       if (have_drawable_releases || sc < 4) {
-               if (sc > 2)
-                       /* back off */
-                       usleep_range(500, 1000);
-
-               if (time_after(jiffies, end))
-                       return 0;
-
-               if (have_drawable_releases && sc > 300) {
-                       DMA_FENCE_WARN(fence,
-                                      "failed to wait on release %llu after spincount %d\n",
-                                      fence->context & ~0xf0000000, sc);
-                       goto signaled;
-               }
-               goto retry;
-       }
-       /*
-        * yeah, original sync_obj_wait gave up after 3 spins when
-        * have_drawable_releases is not set.
-        */
+       if (!wait_event_timeout(qdev->release_event,
+                               (dma_fence_is_signaled(fence) ||
+                                (qxl_io_notify_oom(qdev), 0)),
+                               timeout))
+               return 0;
 
-signaled:
        cur = jiffies;
        if (time_after(cur, end))
                return 0;
index 578a7c37f00bd7a3c8a5f1d5e93d4cd80fdc6cc9..d776e3f87064fa2e86387fb69a0570259ac95fe7 100644 (file)
@@ -92,7 +92,7 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
         */
        if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
                page_flags |= TTM_TT_FLAG_DECRYPTED;
-               drm_info(ddev, "TT memory decryption enabled.");
+               drm_info_once(ddev, "TT memory decryption enabled.");
        }
 
        bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
index e5eb21a471a6010aa956c811522956f27b99a096..00144632c600ebb6a63ab80c55eae90eed95375f 100644 (file)
@@ -204,6 +204,7 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv,
                             VMW_BO_DOMAIN_VRAM,
                             VMW_BO_DOMAIN_VRAM);
        buf->places[0].lpfn = PFN_UP(bo->resource->size);
+       buf->busy_places[0].lpfn = PFN_UP(bo->resource->size);
        ret = ttm_bo_validate(bo, &buf->placement, &ctx);
 
        /* For some reason we didn't end up at the start of vram */
index 2a0cda324703147ef36ff83cd891c70c3395c11d..5efc6a766f64e467a68223376b2a97aa62b278e6 100644 (file)
@@ -991,7 +991,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv,
        }
 
        event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
-       event->event.base.length = sizeof(*event);
+       event->event.base.length = sizeof(event->event);
        event->event.user_data = user_data;
 
        ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
index 420eba0e4be00b8d241bfe2d344837b262095785..854a7bb53567495a4cade766f62c985e8106a70d 100644 (file)
@@ -84,7 +84,8 @@ static inline struct drm_i915_private *kdev_to_i915(struct device *kdev)
 #define IS_ROCKETLAKE(dev_priv)        IS_PLATFORM(dev_priv, XE_ROCKETLAKE)
 #define IS_DG1(dev_priv)        IS_PLATFORM(dev_priv, XE_DG1)
 #define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_S)
-#define IS_ALDERLAKE_P(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_P)
+#define IS_ALDERLAKE_P(dev_priv) (IS_PLATFORM(dev_priv, XE_ALDERLAKE_P) || \
+                                 IS_PLATFORM(dev_priv, XE_ALDERLAKE_N))
 #define IS_XEHPSDV(dev_priv) (dev_priv && 0)
 #define IS_DG2(dev_priv)       IS_PLATFORM(dev_priv, XE_DG2)
 #define IS_PONTEVECCHIO(dev_priv) IS_PLATFORM(dev_priv, XE_PVC)
index 6ad4c1a90a787bfb3fab63d266b86d2cfc9d1b7e..5339f8a490042b6e044803992794ac60c7b9c0b9 100644 (file)
@@ -100,7 +100,7 @@ struct __guc_ads_blob {
        struct guc_engine_usage engine_usage;
        struct guc_um_init_params um_init_params;
        /* From here on, location is dynamic! Refer to above diagram. */
-       struct guc_mmio_reg regset[0];
+       struct guc_mmio_reg regset[];
 } __packed;
 
 #define ads_blob_read(ads_, field_) \
index 7f32547f94b266092afc75bd387f8b6b59f18cec..8bbfa45798e2e73cbd15e5da45a2941cdacb707d 100644 (file)
@@ -120,6 +120,7 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
 {
        struct xe_guc_ct *ct = arg;
 
+       destroy_workqueue(ct->g2h_wq);
        xa_destroy(&ct->fence_lookup);
 }
 
@@ -145,13 +146,20 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
 
        xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
 
-       drmm_mutex_init(&xe->drm, &ct->lock);
+       ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
+       if (!ct->g2h_wq)
+               return -ENOMEM;
+
        spin_lock_init(&ct->fast_lock);
        xa_init(&ct->fence_lookup);
        INIT_WORK(&ct->g2h_worker, g2h_worker_func);
        init_waitqueue_head(&ct->wq);
        init_waitqueue_head(&ct->g2h_fence_wq);
 
+       err = drmm_mutex_init(&xe->drm, &ct->lock);
+       if (err)
+               return err;
+
        primelockdep(ct);
 
        bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
index 5083e099064f4b5cb2f956dd08cfc614c078717e..105bb8e99a8d0f318b0de91954636067698a4e63 100644 (file)
@@ -34,7 +34,7 @@ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct)
                return;
 
        wake_up_all(&ct->wq);
-       queue_work(system_unbound_wq, &ct->g2h_worker);
+       queue_work(ct->g2h_wq, &ct->g2h_worker);
        xe_guc_ct_fast_path(ct);
 }
 
index d29144c9f20bbbfa6d2f0be096f00837dc9ee4c7..fede4c6e93cb6c81d73475c28bcc78c712e78092 100644 (file)
@@ -120,6 +120,8 @@ struct xe_guc_ct {
        wait_queue_head_t wq;
        /** @g2h_fence_wq: wait queue used for G2H fencing */
        wait_queue_head_t g2h_fence_wq;
+       /** @g2h_wq: used to process G2H */
+       struct workqueue_struct *g2h_wq;
        /** @msg: Message buffer */
        u32 msg[GUC_CTB_MSG_MAX_LEN];
        /** @fast_msg: Message buffer */
index 3d4c8f342e215ed39263ba5c4c01079072dfcbbd..32cd0c978aa289efadec2f047dec7dd08b103de3 100644 (file)
@@ -1606,6 +1606,9 @@ static void vm_destroy_work_func(struct work_struct *w)
        /* xe_vm_close_and_put was not called? */
        xe_assert(xe, !vm->size);
 
+       if (xe_vm_in_preempt_fence_mode(vm))
+               flush_work(&vm->preempt.rebind_work);
+
        mutex_destroy(&vm->snap_mutex);
 
        if (!(vm->flags & XE_VM_FLAG_MIGRATION))
index a284a02839fbbd83249c53eb0553c34615c4e22c..3e63666a61bd6b275e7140def18184c968e3fd52 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #define USB_VENDOR_ID_CORSAIR                  0x1b1c
 struct ccp_device {
        struct hid_device *hdev;
        struct device *hwmon_dev;
+       /* For reinitializing the completion below */
+       spinlock_t wait_input_report_lock;
        struct completion wait_input_report;
        struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
+       u8 *cmd_buffer;
        u8 *buffer;
        int target[6];
        DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
@@ -111,15 +115,23 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
        unsigned long t;
        int ret;
 
-       memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE);
-       ccp->buffer[0] = command;
-       ccp->buffer[1] = byte1;
-       ccp->buffer[2] = byte2;
-       ccp->buffer[3] = byte3;
-
+       memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
+       ccp->cmd_buffer[0] = command;
+       ccp->cmd_buffer[1] = byte1;
+       ccp->cmd_buffer[2] = byte2;
+       ccp->cmd_buffer[3] = byte3;
+
+       /*
+        * Disable raw event parsing for a moment to safely reinitialize the
+        * completion. Reinit is done because hidraw could have triggered
+        * the raw event parsing and marked the ccp->wait_input_report
+        * completion as done.
+        */
+       spin_lock_bh(&ccp->wait_input_report_lock);
        reinit_completion(&ccp->wait_input_report);
+       spin_unlock_bh(&ccp->wait_input_report_lock);
 
-       ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE);
+       ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
        if (ret < 0)
                return ret;
 
@@ -135,11 +147,12 @@ static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8
        struct ccp_device *ccp = hid_get_drvdata(hdev);
 
        /* only copy buffer when requested */
-       if (completion_done(&ccp->wait_input_report))
-               return 0;
-
-       memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
-       complete(&ccp->wait_input_report);
+       spin_lock(&ccp->wait_input_report_lock);
+       if (!completion_done(&ccp->wait_input_report)) {
+               memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
+               complete_all(&ccp->wait_input_report);
+       }
+       spin_unlock(&ccp->wait_input_report_lock);
 
        return 0;
 }
@@ -492,7 +505,11 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
        if (!ccp)
                return -ENOMEM;
 
-       ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
+       ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
+       if (!ccp->cmd_buffer)
+               return -ENOMEM;
+
+       ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL);
        if (!ccp->buffer)
                return -ENOMEM;
 
@@ -510,7 +527,9 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
        ccp->hdev = hdev;
        hid_set_drvdata(hdev, ccp);
+
        mutex_init(&ccp->mutex);
+       spin_lock_init(&ccp->wait_input_report_lock);
        init_completion(&ccp->wait_input_report);
 
        hid_device_io_start(hdev);
index 8d9d422450e5cf1d52b74879e8c96d6f5b53654a..d817c719b90bd5d7898b9698922f8d9371737ae9 100644 (file)
@@ -80,11 +80,11 @@ struct ucd9000_debugfs_entry {
  * It has been observed that the UCD90320 randomly fails register access when
  * doing another access right on the back of a register write. To mitigate this
  * make sure that there is a minimum delay between a write access and the
- * following access. The 250us is based on experimental data. At a delay of
- * 200us the issue seems to go away. Add a bit of extra margin to allow for
+ * following access. The 500 is based on experimental data. At a delay of
+ * 350us the issue seems to go away. Add a bit of extra margin to allow for
  * system to system differences.
  */
-#define UCD90320_WAIT_DELAY_US 250
+#define UCD90320_WAIT_DELAY_US 500
 
 static inline void ucd90320_wait(const struct ucd9000_data *data)
 {
index 61839be501c21a023790c15c40f55a48cd8d3da3..63c3566a533bd89429b0104a563f1acc72280ad7 100644 (file)
@@ -5,6 +5,7 @@
  * Copyright (c) 2014, Intel Corporation.
  */
 
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #define MXC4005_REG_ZOUT_UPPER         0x07
 #define MXC4005_REG_ZOUT_LOWER         0x08
 
+#define MXC4005_REG_INT_MASK0          0x0A
+
 #define MXC4005_REG_INT_MASK1          0x0B
 #define MXC4005_REG_INT_MASK1_BIT_DRDYE        0x01
 
+#define MXC4005_REG_INT_CLR0           0x00
+
 #define MXC4005_REG_INT_CLR1           0x01
 #define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
+#define MXC4005_REG_INT_CLR1_SW_RST    0x10
 
 #define MXC4005_REG_CONTROL            0x0D
 #define MXC4005_REG_CONTROL_MASK_FSR   GENMASK(6, 5)
@@ -39,6 +45,9 @@
 
 #define MXC4005_REG_DEVICE_ID          0x0E
 
+/* Datasheet does not specify a reset time, this is a conservative guess */
+#define MXC4005_RESET_TIME_US          2000
+
 enum mxc4005_axis {
        AXIS_X,
        AXIS_Y,
@@ -62,6 +71,8 @@ struct mxc4005_data {
                s64 timestamp __aligned(8);
        } scan;
        bool trigger_enabled;
+       unsigned int control;
+       unsigned int int_mask1;
 };
 
 /*
@@ -113,7 +124,9 @@ static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
 static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
+       case MXC4005_REG_INT_CLR0:
        case MXC4005_REG_INT_CLR1:
+       case MXC4005_REG_INT_MASK0:
        case MXC4005_REG_INT_MASK1:
        case MXC4005_REG_CONTROL:
                return true;
@@ -330,23 +343,20 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig,
 {
        struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
        struct mxc4005_data *data = iio_priv(indio_dev);
+       unsigned int val;
        int ret;
 
        mutex_lock(&data->mutex);
-       if (state) {
-               ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-                                  MXC4005_REG_INT_MASK1_BIT_DRDYE);
-       } else {
-               ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-                                  ~MXC4005_REG_INT_MASK1_BIT_DRDYE);
-       }
 
+       val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, val);
        if (ret < 0) {
                mutex_unlock(&data->mutex);
                dev_err(data->dev, "failed to update reg_int_mask1");
                return ret;
        }
 
+       data->int_mask1 = val;
        data->trigger_enabled = state;
        mutex_unlock(&data->mutex);
 
@@ -382,6 +392,21 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
 
        dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
 
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+                          MXC4005_REG_INT_CLR1_SW_RST);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "resetting chip\n");
+
+       fsleep(MXC4005_RESET_TIME_US);
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "writing INT_MASK0\n");
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, 0);
+       if (ret < 0)
+               return dev_err_probe(data->dev, ret, "writing INT_MASK1\n");
+
        return 0;
 }
 
@@ -469,6 +494,58 @@ static int mxc4005_probe(struct i2c_client *client)
        return devm_iio_device_register(&client->dev, indio_dev);
 }
 
+static int mxc4005_suspend(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct mxc4005_data *data = iio_priv(indio_dev);
+       int ret;
+
+       /* Save control to restore it on resume */
+       ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control);
+       if (ret < 0)
+               dev_err(data->dev, "failed to read reg_control\n");
+
+       return ret;
+}
+
+static int mxc4005_resume(struct device *dev)
+{
+       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct mxc4005_data *data = iio_priv(indio_dev);
+       int ret;
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+                          MXC4005_REG_INT_CLR1_SW_RST);
+       if (ret) {
+               dev_err(data->dev, "failed to reset chip: %d\n", ret);
+               return ret;
+       }
+
+       fsleep(MXC4005_RESET_TIME_US);
+
+       ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control);
+       if (ret) {
+               dev_err(data->dev, "failed to restore control register\n");
+               return ret;
+       }
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+       if (ret) {
+               dev_err(data->dev, "failed to restore interrupt 0 mask\n");
+               return ret;
+       }
+
+       ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1);
+       if (ret) {
+               dev_err(data->dev, "failed to restore interrupt 1 mask\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume);
+
 static const struct acpi_device_id mxc4005_acpi_match[] = {
        {"MXC4005",     0},
        {"MXC6655",     0},
@@ -496,6 +573,7 @@ static struct i2c_driver mxc4005_driver = {
                .name = MXC4005_DRV_NAME,
                .acpi_match_table = mxc4005_acpi_match,
                .of_match_table = mxc4005_of_match,
+               .pm = pm_sleep_ptr(&mxc4005_pm_ops),
        },
        .probe          = mxc4005_probe,
        .id_table       = mxc4005_id,
index 01f55cc902faad356acb1e3f52ea80ea500a4bdb..060a21c70460d290811c28fc9325a6e42df9bb01 100644 (file)
@@ -1289,6 +1289,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
        struct device *dev = &st->adis.spi->dev;
        const struct adis16475_sync *sync;
        u32 sync_mode;
+       u16 val;
 
        /* default to internal clk */
        st->clk_freq = st->info->int_clk * 1000;
@@ -1350,8 +1351,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
         * I'm keeping this for simplicity and avoiding extra variables
         * in chip_info.
         */
+       val = ADIS16475_SYNC_MODE(sync->sync_mode);
        ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
-                                ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
+                                ADIS16475_SYNC_MODE_MASK, val);
        if (ret)
                return ret;
 
index fe8734468ed352589a0d09ddc9c3a3509b3d3fad..62e9e93d915dc8662b672b4aecb44d3ebf3e8081 100644 (file)
@@ -1233,6 +1233,7 @@ const struct bmp280_chip_info bmp380_chip_info = {
        .chip_id = bmp380_chip_ids,
        .num_chip_id = ARRAY_SIZE(bmp380_chip_ids),
        .regmap_config = &bmp380_regmap_config,
+       .spi_read_extra_byte = true,
        .start_up_time = 2000,
        .channels = bmp380_channels,
        .num_channels = 2,
index a444d4b2978b581ed8f4cd63b6821e23a45a0560..4e19ea0b4d398404340338db851b3033db8ab816 100644 (file)
@@ -96,15 +96,10 @@ static int bmp280_spi_probe(struct spi_device *spi)
 
        chip_info = spi_get_device_match_data(spi);
 
-       switch (chip_info->chip_id[0]) {
-       case BMP380_CHIP_ID:
-       case BMP390_CHIP_ID:
+       if (chip_info->spi_read_extra_byte)
                bmp_regmap_bus = &bmp380_regmap_bus;
-               break;
-       default:
+       else
                bmp_regmap_bus = &bmp280_regmap_bus;
-               break;
-       }
 
        regmap = devm_regmap_init(&spi->dev,
                                  bmp_regmap_bus,
@@ -127,7 +122,7 @@ static const struct of_device_id bmp280_of_spi_match[] = {
        { .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
        { .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
        { .compatible = "bosch,bmp280", .data = &bmp280_chip_info },
-       { .compatible = "bosch,bme280", .data = &bmp280_chip_info },
+       { .compatible = "bosch,bme280", .data = &bme280_chip_info },
        { .compatible = "bosch,bmp380", .data = &bmp380_chip_info },
        { .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
        { },
@@ -139,7 +134,7 @@ static const struct spi_device_id bmp280_spi_id[] = {
        { "bmp180", (kernel_ulong_t)&bmp180_chip_info },
        { "bmp181", (kernel_ulong_t)&bmp180_chip_info },
        { "bmp280", (kernel_ulong_t)&bmp280_chip_info },
-       { "bme280", (kernel_ulong_t)&bmp280_chip_info },
+       { "bme280", (kernel_ulong_t)&bme280_chip_info },
        { "bmp380", (kernel_ulong_t)&bmp380_chip_info },
        { "bmp580", (kernel_ulong_t)&bmp580_chip_info },
        { }
index 4012387d79565631e9c8fdd0152f859c80eac485..5812a344ed8e889c441e9b21fc623f98a2e23333 100644 (file)
@@ -423,6 +423,7 @@ struct bmp280_chip_info {
        int num_chip_id;
 
        const struct regmap_config *regmap_config;
+       bool spi_read_extra_byte;
 
        const struct iio_chan_spec *channels;
        int num_channels;
index 455e966eeff3908052384ff5f0af1b98858bfdf4..b27791029fa9349e5c7b8f2a2c8458df9eed4073 100644 (file)
@@ -439,6 +439,7 @@ static int remove_device_files(struct super_block *sb,
                return PTR_ERR(dir);
        }
        simple_recursive_removal(dir, NULL);
+       dput(dir);
        return 0;
 }
 
index f50848ed5575dbe143b159f5c16864fc0cc7b25c..6fadaddb2b908f0b0a2ed5cdd9c8382f08cacae8 100644 (file)
@@ -208,6 +208,7 @@ static const struct xpad_device {
        { 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
        { 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
        { 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
+       { 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE },
        { 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
        { 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
        { 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
@@ -487,6 +488,7 @@ static const struct usb_device_id xpad_table[] = {
        { USB_DEVICE(0x0738, 0x4540) },         /* Mad Catz Beat Pad */
        XPAD_XBOXONE_VENDOR(0x0738),            /* Mad Catz FightStick TE 2 */
        XPAD_XBOX360_VENDOR(0x07ff),            /* Mad Catz Gamepad */
+       XPAD_XBOXONE_VENDOR(0x0b05),            /* ASUS controllers */
        XPAD_XBOX360_VENDOR(0x0c12),            /* Zeroplus X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x0e6f),            /* 0x0e6f Xbox 360 controllers */
        XPAD_XBOXONE_VENDOR(0x0e6f),            /* 0x0e6f Xbox One controllers */
index cda0c3ff5a288df0840011442442e0995330287a..2fbbaeb76d708284e1512ed89fc5a7806c177f1f 100644 (file)
@@ -132,7 +132,13 @@ static void __exit amimouse_remove(struct platform_device *pdev)
        input_unregister_device(dev);
 }
 
-static struct platform_driver amimouse_driver = {
+/*
+ * amimouse_remove() lives in .exit.text. For drivers registered via
+ * module_platform_driver_probe() this is ok because they cannot get unbound at
+ * runtime. So mark the driver struct with __refdata to prevent modpost
+ * triggering a section mismatch warning.
+ */
+static struct platform_driver amimouse_driver __refdata = {
        .remove_new = __exit_p(amimouse_remove),
        .driver   = {
                .name   = "amiga-mouse",
index 64590b86eb37ff3079ed8b5c8dd4c2ad76180206..a8f4b2d70e5956796bd1f583928ec2a00f4df4da 100644 (file)
  * IRQs.
  */
 
-#ifdef __alpha__
-# define I8042_KBD_IRQ 1
-# define I8042_AUX_IRQ (RTC_PORT(0) == 0x170 ? 9 : 12) /* Jensen is special */
-#elif defined(__arm__)
+#if defined(__arm__)
 /* defined in include/asm-arm/arch-xxx/irqs.h */
 #include <asm/irq.h>
 #elif defined(CONFIG_PPC)
index e692217fcb28011478139d7dc146d74dcd9456e8..fb727f5b0b82de427988b76419765a5b8b1ccf46 100644 (file)
@@ -2754,6 +2754,10 @@ static int amd_iommu_def_domain_type(struct device *dev)
        if (!dev_data)
                return 0;
 
+       /* Always use DMA domain for untrusted device */
+       if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted)
+               return IOMMU_DOMAIN_DMA;
+
        /*
         * Do not identity map IOMMUv2 capable devices when:
         *  - memory encryption is active, because some of those devices
index 87bf522b9d2eec034d66bf6c5d144384ae7093fa..957d988b6d832f55a7bbe31adb0b15e89296489d 100644 (file)
@@ -221,11 +221,9 @@ static irqreturn_t nvidia_smmu_context_fault(int irq, void *dev)
        unsigned int inst;
        irqreturn_t ret = IRQ_NONE;
        struct arm_smmu_device *smmu;
-       struct iommu_domain *domain = dev;
-       struct arm_smmu_domain *smmu_domain;
+       struct arm_smmu_domain *smmu_domain = dev;
        struct nvidia_smmu *nvidia;
 
-       smmu_domain = container_of(domain, struct arm_smmu_domain, domain);
        smmu = smmu_domain->smmu;
        nvidia = to_nvidia_smmu(smmu);
 
index 2a537cbfcb077246c0aee43a5b9f1885a3e0b5f2..5f7d3db3afd8248e43e6fc86b677fb0fdc587a84 100644 (file)
@@ -4567,13 +4567,8 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
                irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
        }
 
-       if (err) {
-               if (i > 0)
-                       its_vpe_irq_domain_free(domain, virq, i);
-
-               its_lpi_free(bitmap, base, nr_ids);
-               its_free_prop_table(vprop_page);
-       }
+       if (err)
+               its_vpe_irq_domain_free(domain, virq, i);
 
        return err;
 }
index ea9213f7152e957fa95ce86435d7560033c7b650..4f17a93aa02848c14d414ec35a28eac641b339f8 100644 (file)
@@ -243,6 +243,7 @@ static const struct of_device_id brcmstb_memc_of_match[] = {
        },
        {}
 };
+MODULE_DEVICE_TABLE(of, brcmstb_memc_of_match);
 
 static int brcmstb_memc_suspend(struct device *dev)
 {
index 572c7fbdcfd3a5b929eab83fa98865dd9226d2be..fbe52ecc0eca82ee92292c671ec702d835c2ffa8 100644 (file)
@@ -450,6 +450,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
        {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
        {}
 };
+MODULE_DEVICE_TABLE(of, mtk_smi_larb_of_ids);
 
 static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
 {
@@ -735,6 +736,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
        {.compatible = "mediatek,mt8365-smi-common", .data = &mtk_smi_common_mt8365},
        {}
 };
+MODULE_DEVICE_TABLE(of, mtk_smi_common_of_ids);
 
 static int mtk_smi_common_probe(struct platform_device *pdev)
 {
index aac36750d2c54a658debcca55063d2e2a02bf1ce..c3a6657dcd4a291a09d2f5abf1b0f1d740c10703 100644 (file)
 #define MEI_DEV_ID_ARL_S      0x7F68  /* Arrow Lake Point S */
 #define MEI_DEV_ID_ARL_H      0x7770  /* Arrow Lake Point H */
 
+#define MEI_DEV_ID_LNL_M      0xA870  /* Lunar Lake Point M */
+
 /*
  * MEI HW Section
  */
index c39718042e2e0c9b76da57cfde39f0a0b8801b09..7f59dd38c32f52dccf632fb4bb06066972d26862 100644 (file)
@@ -122,6 +122,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
        {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
 
+       {MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
+
        /* required last entry */
        {0, }
 };
index b1e4c23b31a32957c616f0edcdf74dc086c44a89..49abc95677cdac6a74d673cbf5444ccc82deee74 100644 (file)
@@ -236,8 +236,11 @@ static int mei_pxp_component_match(struct device *dev, int subcomponent,
 
        pdev = to_pci_dev(dev);
 
-       if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
-           pdev->vendor != PCI_VENDOR_ID_INTEL)
+       if (pdev->vendor != PCI_VENDOR_ID_INTEL)
+               return 0;
+
+       if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) &&
+           pdev->class != (PCI_CLASS_DISPLAY_OTHER << 8))
                return 0;
 
        if (subcomponent != I915_COMPONENT_PXP)
index 9ad20e82785bcd6ade57d493e31152ecff334178..b21598a18f6da81568dedb0817bf74da55f81a15 100644 (file)
@@ -44,8 +44,6 @@ static struct pci_driver pvpanic_pci_driver = {
        .name =         "pvpanic-pci",
        .id_table =     pvpanic_pci_id_tbl,
        .probe =        pvpanic_pci_probe,
-       .driver = {
-               .dev_groups = pvpanic_dev_groups,
-       },
+       .dev_groups =   pvpanic_dev_groups,
 };
 module_pci_driver(pvpanic_pci_driver);
index 59b5dd0e2f41d2a8751a4f5139e39302acb2b7bd..0918bd6fa81ddfb0a4d0bc6fb98a9a604f094c86 100644 (file)
@@ -637,12 +637,12 @@ static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
                                   MAC_1000FD;
 }
 
-static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
+static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port)
 {
        u16 reg, val;
        int err;
 
-       err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &reg);
+       err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
        if (err)
                return err;
 
@@ -651,16 +651,16 @@ static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
                return 0xf;
 
        val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT;
-       err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, val);
+       err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val);
        if (err)
                return err;
 
-       err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &val);
+       err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val);
        if (err)
                return err;
 
        /* Restore PHY_DETECT value */
-       err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, reg);
+       err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
        if (err)
                return err;
 
@@ -688,7 +688,30 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
                if (err <= 0)
                        return;
 
-               cmode = mv88e6352_get_port4_serdes_cmode(chip);
+               cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
+               if (cmode < 0)
+                       dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
+                               port);
+               else
+                       mv88e6xxx_translate_cmode(cmode, supported);
+       }
+}
+
+static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+                                      struct phylink_config *config)
+{
+       unsigned long *supported = config->supported_interfaces;
+       int cmode;
+
+       /* Translate the default cmode */
+       mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+
+       config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
+                                  MAC_1000FD;
+
+       /* Port 0/1 are serdes only ports */
+       if (port == 0 || port == 1) {
+               cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
                if (cmode < 0)
                        dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
                                port);
@@ -5093,7 +5116,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
        .gpio_ops = &mv88e6352_gpio_ops,
        .avb_ops = &mv88e6352_avb_ops,
        .ptp_ops = &mv88e6352_ptp_ops,
-       .phylink_get_caps = mv88e6185_phylink_get_caps,
+       .phylink_get_caps = mv88e632x_phylink_get_caps,
 };
 
 static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -5139,7 +5162,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
        .gpio_ops = &mv88e6352_gpio_ops,
        .avb_ops = &mv88e6352_avb_ops,
        .ptp_ops = &mv88e6352_ptp_ops,
-       .phylink_get_caps = mv88e6185_phylink_get_caps,
+       .phylink_get_caps = mv88e632x_phylink_get_caps,
 };
 
 static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -5705,7 +5728,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
                .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
                .family = MV88E6XXX_FAMILY_6341,
                .name = "Marvell 88E6141",
-               .num_databases = 4096,
+               .num_databases = 256,
                .num_macs = 2048,
                .num_ports = 6,
                .num_internal_phys = 5,
@@ -6164,7 +6187,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
                .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
                .family = MV88E6XXX_FAMILY_6341,
                .name = "Marvell 88E6341",
-               .num_databases = 4096,
+               .num_databases = 256,
                .num_macs = 2048,
                .num_internal_phys = 5,
                .num_ports = 6,
index b1f84b37032a7833d7e4f3d045e8755ace6f79d3..c7e7dac057a336d086bdf9569286fadec7e1d3be 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) controller driver
  *
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #define pr_fmt(fmt)                            "bcmgenet: " fmt
@@ -2467,14 +2467,18 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable)
 {
        u32 reg;
 
+       spin_lock_bh(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-       if (reg & CMD_SW_RESET)
+       if (reg & CMD_SW_RESET) {
+               spin_unlock_bh(&priv->reg_lock);
                return;
+       }
        if (enable)
                reg |= mask;
        else
                reg &= ~mask;
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+       spin_unlock_bh(&priv->reg_lock);
 
        /* UniMAC stops on a packet boundary, wait for a full-size packet
         * to be processed
@@ -2490,8 +2494,10 @@ static void reset_umac(struct bcmgenet_priv *priv)
        udelay(10);
 
        /* issue soft reset and disable MAC while updating its registers */
+       spin_lock_bh(&priv->reg_lock);
        bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
        udelay(2);
+       spin_unlock_bh(&priv->reg_lock);
 }
 
 static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
@@ -3334,7 +3340,9 @@ static void bcmgenet_netif_start(struct net_device *dev)
        struct bcmgenet_priv *priv = netdev_priv(dev);
 
        /* Start the network engine */
+       netif_addr_lock_bh(dev);
        bcmgenet_set_rx_mode(dev);
+       netif_addr_unlock_bh(dev);
        bcmgenet_enable_rx_napi(priv);
 
        umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
@@ -3595,16 +3603,19 @@ static void bcmgenet_set_rx_mode(struct net_device *dev)
         * 3. The number of filters needed exceeds the number filters
         *    supported by the hardware.
        */
+       spin_lock(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
        if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
            (nfilter > MAX_MDF_FILTER)) {
                reg |= CMD_PROMISC;
                bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+               spin_unlock(&priv->reg_lock);
                bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
                return;
        } else {
                reg &= ~CMD_PROMISC;
                bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+               spin_unlock(&priv->reg_lock);
        }
 
        /* update MDF filter */
@@ -4003,6 +4014,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
                goto err;
        }
 
+       spin_lock_init(&priv->reg_lock);
        spin_lock_init(&priv->lock);
 
        /* Set default pause parameters */
index 7523b60b3c1c016de74fd74b7d1e286596aac1ae..43b923c48b14f40e0cf9cdd6b6f3ac16c301ef97 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #ifndef __BCMGENET_H__
@@ -573,6 +573,8 @@ struct bcmgenet_rxnfc_rule {
 /* device context */
 struct bcmgenet_priv {
        void __iomem *base;
+       /* reg_lock: lock to serialize access to shared registers */
+       spinlock_t reg_lock;
        enum bcmgenet_version version;
        struct net_device *dev;
 
index 7a41cad5788f4edd6691552901f4b2eb8fdebc36..1248792d7fd4d2f98847889c499277a92229d785 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
  *
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #define pr_fmt(fmt)                            "bcmgenet_wol: " fmt
@@ -151,6 +151,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
        }
 
        /* Can't suspend with WoL if MAC is still in reset */
+       spin_lock_bh(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
        if (reg & CMD_SW_RESET)
                reg &= ~CMD_SW_RESET;
@@ -158,6 +159,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
        /* disable RX */
        reg &= ~CMD_RX_EN;
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+       spin_unlock_bh(&priv->reg_lock);
        mdelay(10);
 
        if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
@@ -203,6 +205,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
        }
 
        /* Enable CRC forward */
+       spin_lock_bh(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
        priv->crc_fwd_en = 1;
        reg |= CMD_CRC_FWD;
@@ -210,6 +213,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
        /* Receiver must be enabled for WOL MP detection */
        reg |= CMD_RX_EN;
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+       spin_unlock_bh(&priv->reg_lock);
 
        reg = UMAC_IRQ_MPD_R;
        if (hfb_enable)
@@ -256,7 +260,9 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
        }
 
        /* Disable CRC Forward */
+       spin_lock_bh(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
        reg &= ~CMD_CRC_FWD;
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+       spin_unlock_bh(&priv->reg_lock);
 }
index 9ada89355747554dc458c311f96333866cf7bc66..c4a3698cef66f61d775c783b334a035589d55bdd 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET MDIO routines
  *
- * Copyright (c) 2014-2017 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #include <linux/acpi.h>
@@ -76,6 +76,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
        reg |= RGMII_LINK;
        bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
 
+       spin_lock_bh(&priv->reg_lock);
        reg = bcmgenet_umac_readl(priv, UMAC_CMD);
        reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
                       CMD_HD_EN |
@@ -88,6 +89,7 @@ static void bcmgenet_mac_config(struct net_device *dev)
                reg |= CMD_TX_EN | CMD_RX_EN;
        }
        bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+       spin_unlock_bh(&priv->reg_lock);
 
        active = phy_init_eee(phydev, 0) >= 0;
        bcmgenet_eee_enable_set(dev,
@@ -275,6 +277,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
         * block for the interface to work, unconditionally clear the
         * Out-of-band disable since we do not need it.
         */
+       mutex_lock(&phydev->lock);
        reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
        reg &= ~OOB_DISABLE;
        if (priv->ext_phy) {
@@ -286,6 +289,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
                        reg |= RGMII_MODE_EN;
        }
        bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
+       mutex_unlock(&phydev->lock);
 
        if (init)
                dev_info(kdev, "configuring instance for %s\n", phy_name);
index 7246e13dd559fc37170c791644cf5a8fd8d04fcf..97291bfbeea589e8ca8ab637db8bcff7e573322f 100644 (file)
@@ -312,7 +312,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
        void *kern_buf;
 
        /* Copy the user space buf */
-       kern_buf = memdup_user(buf, nbytes);
+       kern_buf = memdup_user_nul(buf, nbytes);
        if (IS_ERR(kern_buf))
                return PTR_ERR(kern_buf);
 
@@ -372,7 +372,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf,
        void *kern_buf;
 
        /* Copy the user space buf */
-       kern_buf = memdup_user(buf, nbytes);
+       kern_buf = memdup_user_nul(buf, nbytes);
        if (IS_ERR(kern_buf))
                return PTR_ERR(kern_buf);
 
index 49d5808b7d11d281796debc6be5f9b3a9b1f60e3..de52bcb884c417098ff5aff6aea77753d055c671 100644 (file)
@@ -2670,12 +2670,12 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
        lb->loopback = 1;
 
        q = &adap->sge.ethtxq[pi->first_qset];
-       __netif_tx_lock(q->txq, smp_processor_id());
+       __netif_tx_lock_bh(q->txq);
 
        reclaim_completed_tx(adap, &q->q, -1, true);
        credits = txq_avail(&q->q) - ndesc;
        if (unlikely(credits < 0)) {
-               __netif_tx_unlock(q->txq);
+               __netif_tx_unlock_bh(q->txq);
                return -ENOMEM;
        }
 
@@ -2710,7 +2710,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
        init_completion(&lb->completion);
        txq_advance(&q->q, ndesc);
        cxgb4_ring_tx_db(adap, &q->q, ndesc);
-       __netif_tx_unlock(q->txq);
+       __netif_tx_unlock_bh(q->txq);
 
        /* wait for the pkt to return */
        ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
index f19f1e1d1f9f036005e59ea3ceea722b7d870fa0..133c94646c21db4f93220778ff42f31c0ecad301 100644 (file)
@@ -897,7 +897,7 @@ struct hnae3_handle {
                struct hnae3_roce_private_info rinfo;
        };
 
-       u32 numa_node_mask;     /* for multi-chip support */
+       nodemask_t numa_node_mask; /* for multi-chip support */
 
        enum hnae3_port_base_vlan_state port_base_vlan_state;
 
index ff6a2ed23ddb6be2c5dd132698d2fd079f5f5827..ce60332d83c39cbe5f6e60a51f6cd9b61b69333f 100644 (file)
@@ -1537,6 +1537,9 @@ static int hclge_configure(struct hclge_dev *hdev)
                        cfg.default_speed, ret);
                return ret;
        }
+       hdev->hw.mac.req_speed = hdev->hw.mac.speed;
+       hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
+       hdev->hw.mac.req_duplex = DUPLEX_FULL;
 
        hclge_parse_link_mode(hdev, cfg.speed_ability);
 
@@ -1766,7 +1769,8 @@ static int hclge_vport_setup(struct hclge_vport *vport, u16 num_tqps)
 
        nic->pdev = hdev->pdev;
        nic->ae_algo = &ae_algo;
-       nic->numa_node_mask = hdev->numa_node_mask;
+       bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
+                   MAX_NUMNODES);
        nic->kinfo.io_base = hdev->hw.hw.io_base;
 
        ret = hclge_knic_setup(vport, num_tqps,
@@ -2458,7 +2462,8 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport)
 
        roce->pdev = nic->pdev;
        roce->ae_algo = nic->ae_algo;
-       roce->numa_node_mask = nic->numa_node_mask;
+       bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
+                   MAX_NUMNODES);
 
        return 0;
 }
@@ -3342,9 +3347,9 @@ hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
                return ret;
        }
 
-       hdev->hw.mac.autoneg = cmd->base.autoneg;
-       hdev->hw.mac.speed = cmd->base.speed;
-       hdev->hw.mac.duplex = cmd->base.duplex;
+       hdev->hw.mac.req_autoneg = cmd->base.autoneg;
+       hdev->hw.mac.req_speed = cmd->base.speed;
+       hdev->hw.mac.req_duplex = cmd->base.duplex;
        linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
 
        return 0;
@@ -3377,9 +3382,9 @@ static int hclge_tp_port_init(struct hclge_dev *hdev)
        if (!hnae3_dev_phy_imp_supported(hdev))
                return 0;
 
-       cmd.base.autoneg = hdev->hw.mac.autoneg;
-       cmd.base.speed = hdev->hw.mac.speed;
-       cmd.base.duplex = hdev->hw.mac.duplex;
+       cmd.base.autoneg = hdev->hw.mac.req_autoneg;
+       cmd.base.speed = hdev->hw.mac.req_speed;
+       cmd.base.duplex = hdev->hw.mac.req_duplex;
        linkmode_copy(cmd.link_modes.advertising, hdev->hw.mac.advertising);
 
        return hclge_set_phy_link_ksettings(&hdev->vport->nic, &cmd);
@@ -7952,8 +7957,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
                /* Set the DOWN flag here to disable link updating */
                set_bit(HCLGE_STATE_DOWN, &hdev->state);
 
-               /* flush memory to make sure DOWN is seen by service task */
-               smp_mb__before_atomic();
+               smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
                hclge_flush_link_update(hdev);
        }
 }
@@ -9906,6 +9910,7 @@ static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
 static int hclge_init_vlan_filter(struct hclge_dev *hdev)
 {
        struct hclge_vport *vport;
+       bool enable = true;
        int ret;
        int i;
 
@@ -9925,8 +9930,12 @@ static int hclge_init_vlan_filter(struct hclge_dev *hdev)
                vport->cur_vlan_fltr_en = true;
        }
 
+       if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps) &&
+           !test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, hdev->ae_dev->caps))
+               enable = false;
+
        return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
-                                         HCLGE_FILTER_FE_INGRESS, true, 0);
+                                         HCLGE_FILTER_FE_INGRESS, enable, 0);
 }
 
 static int hclge_init_vlan_type(struct hclge_dev *hdev)
@@ -11622,16 +11631,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
        if (ret)
                goto out;
 
-       ret = hclge_devlink_init(hdev);
-       if (ret)
-               goto err_pci_uninit;
-
-       devl_lock(hdev->devlink);
-
        /* Firmware command queue initialize */
        ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
        if (ret)
-               goto err_devlink_uninit;
+               goto err_pci_uninit;
 
        /* Firmware command initialize */
        ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version,
@@ -11759,7 +11762,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
 
        ret = hclge_update_port_info(hdev);
        if (ret)
-               goto err_mdiobus_unreg;
+               goto err_ptp_uninit;
 
        INIT_KFIFO(hdev->mac_tnl_log);
 
@@ -11799,6 +11802,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
                dev_warn(&pdev->dev,
                         "failed to wake on lan init, ret = %d\n", ret);
 
+       ret = hclge_devlink_init(hdev);
+       if (ret)
+               goto err_ptp_uninit;
+
        hclge_state_init(hdev);
        hdev->last_reset_time = jiffies;
 
@@ -11806,10 +11813,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
                 HCLGE_DRIVER_NAME);
 
        hclge_task_schedule(hdev, round_jiffies_relative(HZ));
-
-       devl_unlock(hdev->devlink);
        return 0;
 
+err_ptp_uninit:
+       hclge_ptp_uninit(hdev);
 err_mdiobus_unreg:
        if (hdev->hw.mac.phydev)
                mdiobus_unregister(hdev->hw.mac.mdio_bus);
@@ -11819,9 +11826,6 @@ err_msi_uninit:
        pci_free_irq_vectors(pdev);
 err_cmd_uninit:
        hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
-err_devlink_uninit:
-       devl_unlock(hdev->devlink);
-       hclge_devlink_uninit(hdev);
 err_pci_uninit:
        pcim_iounmap(pdev, hdev->hw.hw.io_base);
        pci_release_regions(pdev);
index e821dd2f15289012651bb5a4d0ac5cfb6cfbec3a..3a9186457ad89667c6e5edae725bc711ddb34abe 100644 (file)
@@ -279,11 +279,14 @@ struct hclge_mac {
        u8 media_type;  /* port media type, e.g. fibre/copper/backplane */
        u8 mac_addr[ETH_ALEN];
        u8 autoneg;
+       u8 req_autoneg;
        u8 duplex;
+       u8 req_duplex;
        u8 support_autoneg;
        u8 speed_type;  /* 0: sfp speed, 1: active speed */
        u8 lane_num;
        u32 speed;
+       u32 req_speed;
        u32 max_speed;
        u32 speed_ability; /* speed ability supported by current media */
        u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
@@ -891,7 +894,7 @@ struct hclge_dev {
 
        u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
        u16 num_alloc_vport;            /* Num vports this driver supports */
-       u32 numa_node_mask;
+       nodemask_t numa_node_mask;
        u16 rx_buf_len;
        u16 num_tx_desc;                /* desc num of per tx queue */
        u16 num_rx_desc;                /* desc num of per rx queue */
index d4a0e0be7a7230054d4e523ec463a16f52b9592e..59c863306657fa9315fe7d290387f73f3a818f16 100644 (file)
@@ -1077,12 +1077,13 @@ static void hclge_mbx_request_handling(struct hclge_mbx_ops_param *param)
 
        hdev = param->vport->back;
        cmd_func = hclge_mbx_ops_list[param->req->msg.code];
-       if (cmd_func)
-               ret = cmd_func(param);
-       else
+       if (!cmd_func) {
                dev_err(&hdev->pdev->dev,
                        "un-supported mailbox message, code = %u\n",
                        param->req->msg.code);
+               return;
+       }
+       ret = cmd_func(param);
 
        /* PF driver should not reply IMP */
        if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
index 0aa9beefd1c7ee6c53d9f2623069bae00848e77f..43ee20eb03d1fb1abf9b655661bf5f572c5de82e 100644 (file)
@@ -412,7 +412,8 @@ static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
 
        nic->ae_algo = &ae_algovf;
        nic->pdev = hdev->pdev;
-       nic->numa_node_mask = hdev->numa_node_mask;
+       bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
+                   MAX_NUMNODES);
        nic->flags |= HNAE3_SUPPORT_VF;
        nic->kinfo.io_base = hdev->hw.hw.io_base;
 
@@ -2082,8 +2083,8 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
 
        roce->pdev = nic->pdev;
        roce->ae_algo = nic->ae_algo;
-       roce->numa_node_mask = nic->numa_node_mask;
-
+       bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
+                   MAX_NUMNODES);
        return 0;
 }
 
@@ -2180,8 +2181,7 @@ static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable)
        } else {
                set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
 
-               /* flush memory to make sure DOWN is seen by service task */
-               smp_mb__before_atomic();
+               smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
                hclgevf_flush_link_update(hdev);
        }
 }
@@ -2845,10 +2845,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
        if (ret)
                return ret;
 
-       ret = hclgevf_devlink_init(hdev);
-       if (ret)
-               goto err_devlink_init;
-
        ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
        if (ret)
                goto err_cmd_queue_init;
@@ -2941,6 +2937,10 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
 
        hclgevf_init_rxd_adv_layout(hdev);
 
+       ret = hclgevf_devlink_init(hdev);
+       if (ret)
+               goto err_config;
+
        set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
 
        hdev->last_reset_time = jiffies;
@@ -2960,8 +2960,6 @@ err_misc_irq_init:
 err_cmd_init:
        hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
 err_cmd_queue_init:
-       hclgevf_devlink_uninit(hdev);
-err_devlink_init:
        hclgevf_pci_uninit(hdev);
        clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
        return ret;
index a73f2bf3a56a6426704c64a20e74403c715ac09f..cccef32284616bd62885ca130e19dcbe5e5cfc8a 100644 (file)
@@ -236,7 +236,7 @@ struct hclgevf_dev {
        u16 rss_size_max;       /* HW defined max RSS task queue */
 
        u16 num_alloc_vport;    /* num vports this driver supports */
-       u32 numa_node_mask;
+       nodemask_t numa_node_mask;
        u16 rx_buf_len;
        u16 num_tx_desc;        /* desc num of per tx queue */
        u16 num_rx_desc;        /* desc num of per rx queue */
index 93544f1cc2a51be0c84c33391211bf47d2675edb..f7ae0e0aa4a4f52d7ff720c11fb906cac00f7c5a 100644 (file)
@@ -157,7 +157,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
                 * the lower time out
                 */
                for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-                       usleep_range(50, 60);
+                       udelay(50);
                        mdic = er32(MDIC);
                        if (mdic & E1000_MDIC_READY)
                                break;
@@ -181,7 +181,7 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
                 * reading duplicate data in the next MDIC transaction.
                 */
                if (hw->mac.type == e1000_pch2lan)
-                       usleep_range(100, 150);
+                       udelay(100);
 
                if (success) {
                        *data = (u16)mdic;
@@ -237,7 +237,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
                 * the lower time out
                 */
                for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-                       usleep_range(50, 60);
+                       udelay(50);
                        mdic = er32(MDIC);
                        if (mdic & E1000_MDIC_READY)
                                break;
@@ -261,7 +261,7 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
                 * reading duplicate data in the next MDIC transaction.
                 */
                if (hw->mac.type == e1000_pch2lan)
-                       usleep_range(100, 150);
+                       udelay(100);
 
                if (success)
                        return 0;
index d252d98218d084e9782d899d4f854c0bf7101622..9fc0fd95a13d8f2c40475a94f38d3a2c088ab6f4 100644 (file)
@@ -171,7 +171,7 @@ ice_debugfs_module_write(struct file *filp, const char __user *buf,
        if (*ppos != 0 || count > 8)
                return -EINVAL;
 
-       cmd_buf = memdup_user(buf, count);
+       cmd_buf = memdup_user_nul(buf, count);
        if (IS_ERR(cmd_buf))
                return PTR_ERR(cmd_buf);
 
@@ -257,7 +257,7 @@ ice_debugfs_nr_messages_write(struct file *filp, const char __user *buf,
        if (*ppos != 0 || count > 4)
                return -EINVAL;
 
-       cmd_buf = memdup_user(buf, count);
+       cmd_buf = memdup_user_nul(buf, count);
        if (IS_ERR(cmd_buf))
                return PTR_ERR(cmd_buf);
 
@@ -332,7 +332,7 @@ ice_debugfs_enable_write(struct file *filp, const char __user *buf,
        if (*ppos != 0 || count > 2)
                return -EINVAL;
 
-       cmd_buf = memdup_user(buf, count);
+       cmd_buf = memdup_user_nul(buf, count);
        if (IS_ERR(cmd_buf))
                return PTR_ERR(cmd_buf);
 
@@ -428,7 +428,7 @@ ice_debugfs_log_size_write(struct file *filp, const char __user *buf,
        if (*ppos != 0 || count > 5)
                return -EINVAL;
 
-       cmd_buf = memdup_user(buf, count);
+       cmd_buf = memdup_user_nul(buf, count);
        if (IS_ERR(cmd_buf))
                return PTR_ERR(cmd_buf);
 
index 2500f5ba4f5a42b43ee5de8d64d7f06fb70cdd87..881d704644fbee77cf5c9f7137d539463c08c2dd 100644 (file)
@@ -999,12 +999,10 @@ static ssize_t rvu_dbg_qsize_write(struct file *filp,
        u16 pcifunc;
        int ret, lf;
 
-       cmd_buf = memdup_user(buffer, count + 1);
+       cmd_buf = memdup_user_nul(buffer, count);
        if (IS_ERR(cmd_buf))
                return -ENOMEM;
 
-       cmd_buf[count] = '\0';
-
        cmd_buf_tmp = strchr(cmd_buf, '\n');
        if (cmd_buf_tmp) {
                *cmd_buf_tmp = '\0';
index d4cdf3d4f55257ad5ace878f87abf5d96f67b001..502518cdb461887d4eaf86b11ecf8203deb6edc9 100644 (file)
@@ -234,12 +234,13 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt)
 /**
  * ks8851_rx_pkts - receive packets from the host
  * @ks: The device information.
+ * @rxq: Queue of packets received in this function.
  *
  * This is called from the IRQ work queue when the system detects that there
  * are packets in the receive queue. Find out how many packets there are and
  * read them from the FIFO.
  */
-static void ks8851_rx_pkts(struct ks8851_net *ks)
+static void ks8851_rx_pkts(struct ks8851_net *ks, struct sk_buff_head *rxq)
 {
        struct sk_buff *skb;
        unsigned rxfc;
@@ -299,7 +300,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
                                        ks8851_dbg_dumpkkt(ks, rxpkt);
 
                                skb->protocol = eth_type_trans(skb, ks->netdev);
-                               __netif_rx(skb);
+                               __skb_queue_tail(rxq, skb);
 
                                ks->netdev->stats.rx_packets++;
                                ks->netdev->stats.rx_bytes += rxlen;
@@ -326,11 +327,11 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
 static irqreturn_t ks8851_irq(int irq, void *_ks)
 {
        struct ks8851_net *ks = _ks;
+       struct sk_buff_head rxq;
        unsigned handled = 0;
        unsigned long flags;
        unsigned int status;
-
-       local_bh_disable();
+       struct sk_buff *skb;
 
        ks8851_lock(ks, &flags);
 
@@ -384,7 +385,8 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
                 * from the device so do not bother masking just the RX
                 * from the device. */
 
-               ks8851_rx_pkts(ks);
+               __skb_queue_head_init(&rxq);
+               ks8851_rx_pkts(ks, &rxq);
        }
 
        /* if something stopped the rx process, probably due to wanting
@@ -408,7 +410,9 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
        if (status & IRQ_LCI)
                mii_check_link(&ks->mii);
 
-       local_bh_enable();
+       if (status & IRQ_RXI)
+               while ((skb = __skb_dequeue(&rxq)))
+                       netif_rx(skb);
 
        return IRQ_HANDLED;
 }
index a5ac21a0ee33ff01e8bcdcf5757a76a863d6543b..cb6b33a228ea2063edd4f795a1f3368d1fbc483a 100644 (file)
@@ -1868,8 +1868,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
                            struct flow_cls_offload *f)
 {
        struct qede_arfs_fltr_node *n;
-       int min_hlen, rc = -EINVAL;
        struct qede_arfs_tuple t;
+       int min_hlen, rc;
 
        __qede_lock(edev);
 
@@ -1879,7 +1879,8 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
        }
 
        /* parse flower attribute and prepare filter */
-       if (qede_parse_flow_attr(edev, proto, f->rule, &t))
+       rc = qede_parse_flow_attr(edev, proto, f->rule, &t);
+       if (rc)
                goto unlock;
 
        /* Validate profile mode and number of filters */
@@ -1888,11 +1889,13 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto,
                DP_NOTICE(edev,
                          "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n",
                          t.mode, edev->arfs->mode, edev->arfs->filter_count);
+               rc = -EINVAL;
                goto unlock;
        }
 
        /* parse tc actions and get the vf_id */
-       if (qede_parse_actions(edev, &f->rule->action, f->common.extack))
+       rc = qede_parse_actions(edev, &f->rule->action, f->common.extack);
+       if (rc)
                goto unlock;
 
        if (qede_flow_find_fltr(edev, &t)) {
@@ -1998,10 +2001,9 @@ static int qede_flow_spec_to_rule(struct qede_dev *edev,
        if (IS_ERR(flow))
                return PTR_ERR(flow);
 
-       if (qede_parse_flow_attr(edev, proto, flow->rule, t)) {
-               err = -EINVAL;
+       err = qede_parse_flow_attr(edev, proto, flow->rule, t);
+       if (err)
                goto err_out;
-       }
 
        /* Make sure location is valid and filter isn't already set */
        err = qede_flow_spec_validate(edev, &flow->rule->action, t,
index 6b4bd98833043a3a1bf49024f28747b5bf77c66b..c812f16eaa3a886b3cf1745db4464d7bacb0920f 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/hwmon.h>
 
 #define PHY_ID_88Q2220_REVB0   (MARVELL_PHY_ID_88Q2220 | 0x1)
+#define PHY_ID_88Q2220_REVB1   (MARVELL_PHY_ID_88Q2220 | 0x2)
+#define PHY_ID_88Q2220_REVB2   (MARVELL_PHY_ID_88Q2220 | 0x3)
 
 #define MDIO_MMD_AN_MV_STAT                    32769
 #define MDIO_MMD_AN_MV_STAT_ANEG               0x0100
@@ -129,6 +131,49 @@ static const struct mmd_val mv88q222x_revb0_init_seq1[] = {
        { MDIO_MMD_PCS, 0xfe05, 0x755c },
 };
 
+static const struct mmd_val mv88q222x_revb1_init_seq0[] = {
+       { MDIO_MMD_PCS, 0xffe4, 0x0007 },
+       { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
+       { MDIO_MMD_PCS, 0xffe3, 0x7000 },
+       { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
+};
+
+static const struct mmd_val mv88q222x_revb2_init_seq0[] = {
+       { MDIO_MMD_PCS, 0xffe4, 0x0007 },
+       { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
+       { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
+};
+
+static const struct mmd_val mv88q222x_revb1_revb2_init_seq1[] = {
+       { MDIO_MMD_PCS, 0xfe07, 0x125a },
+       { MDIO_MMD_PCS, 0xfe09, 0x1288 },
+       { MDIO_MMD_PCS, 0xfe08, 0x2588 },
+       { MDIO_MMD_PCS, 0xfe72, 0x042c },
+       { MDIO_MMD_PCS, 0xffe4, 0x0071 },
+       { MDIO_MMD_PCS, 0xffe4, 0x0001 },
+       { MDIO_MMD_PCS, 0xfe1b, 0x0048 },
+       { MDIO_MMD_PMAPMD, 0x0000, 0x0000 },
+       { MDIO_MMD_PCS, 0x0000, 0x0000 },
+       { MDIO_MMD_PCS, 0xffdb, 0xfc10 },
+       { MDIO_MMD_PCS, 0xfe1b, 0x58 },
+       { MDIO_MMD_PCS, 0xfcad, 0x030c },
+       { MDIO_MMD_PCS, 0x8032, 0x6001 },
+       { MDIO_MMD_PCS, 0xfdff, 0x05a5 },
+       { MDIO_MMD_PCS, 0xfdec, 0xdbaf },
+       { MDIO_MMD_PCS, 0xfcab, 0x1054 },
+       { MDIO_MMD_PCS, 0xfcac, 0x1483 },
+       { MDIO_MMD_PCS, 0x8033, 0xc801 },
+       { MDIO_MMD_AN, 0x8032, 0x2020 },
+       { MDIO_MMD_AN, 0x8031, 0xa28 },
+       { MDIO_MMD_AN, 0x8031, 0xc28 },
+       { MDIO_MMD_PCS, 0xfbba, 0x0cb2 },
+       { MDIO_MMD_PCS, 0xfbbb, 0x0c4a },
+       { MDIO_MMD_PCS, 0xfe5f, 0xe8 },
+       { MDIO_MMD_PCS, 0xfe05, 0x755c },
+       { MDIO_MMD_PCS, 0xfa20, 0x002a },
+       { MDIO_MMD_PCS, 0xfe11, 0x1105 },
+};
+
 static int mv88q2xxx_soft_reset(struct phy_device *phydev)
 {
        int ret;
@@ -687,31 +732,72 @@ static int mv88q222x_soft_reset(struct phy_device *phydev)
        return 0;
 }
 
-static int mv88q222x_revb0_config_init(struct phy_device *phydev)
+static int mv88q222x_write_mmd_vals(struct phy_device *phydev,
+                                   const struct mmd_val *vals, size_t len)
 {
-       int ret, i;
+       int ret;
 
-       for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq0); i++) {
-               ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq0[i].devad,
-                                   mv88q222x_revb0_init_seq0[i].regnum,
-                                   mv88q222x_revb0_init_seq0[i].val);
+       for (; len; vals++, len--) {
+               ret = phy_write_mmd(phydev, vals->devad, vals->regnum,
+                                   vals->val);
                if (ret < 0)
                        return ret;
        }
 
+       return 0;
+}
+
+static int mv88q222x_revb0_config_init(struct phy_device *phydev)
+{
+       int ret;
+
+       ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq0,
+                                      ARRAY_SIZE(mv88q222x_revb0_init_seq0));
+       if (ret < 0)
+               return ret;
+
        usleep_range(5000, 10000);
 
-       for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq1); i++) {
-               ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq1[i].devad,
-                                   mv88q222x_revb0_init_seq1[i].regnum,
-                                   mv88q222x_revb0_init_seq1[i].val);
-               if (ret < 0)
-                       return ret;
-       }
+       ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq1,
+                                      ARRAY_SIZE(mv88q222x_revb0_init_seq1));
+       if (ret < 0)
+               return ret;
+
+       return mv88q2xxx_config_init(phydev);
+}
+
+static int mv88q222x_revb1_revb2_config_init(struct phy_device *phydev)
+{
+       bool is_rev_b1 = phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB1;
+       int ret;
+
+       if (is_rev_b1)
+               ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_init_seq0,
+                                              ARRAY_SIZE(mv88q222x_revb1_init_seq0));
+       else
+               ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb2_init_seq0,
+                                              ARRAY_SIZE(mv88q222x_revb2_init_seq0));
+       if (ret < 0)
+               return ret;
+
+       usleep_range(3000, 5000);
+
+       ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_revb2_init_seq1,
+                                      ARRAY_SIZE(mv88q222x_revb1_revb2_init_seq1));
+       if (ret < 0)
+               return ret;
 
        return mv88q2xxx_config_init(phydev);
 }
 
+static int mv88q222x_config_init(struct phy_device *phydev)
+{
+       if (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB0)
+               return mv88q222x_revb0_config_init(phydev);
+       else
+               return mv88q222x_revb1_revb2_config_init(phydev);
+}
+
 static int mv88q222x_cable_test_start(struct phy_device *phydev)
 {
        int ret;
@@ -810,14 +896,15 @@ static struct phy_driver mv88q2xxx_driver[] = {
                .get_sqi_max            = mv88q2xxx_get_sqi_max,
        },
        {
-               PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0),
+               .phy_id                 = MARVELL_PHY_ID_88Q2220,
+               .phy_id_mask            = MARVELL_PHY_ID_MASK,
                .name                   = "mv88q2220",
                .flags                  = PHY_POLL_CABLE_TEST,
                .probe                  = mv88q2xxx_probe,
                .get_features           = mv88q2xxx_get_features,
                .config_aneg            = mv88q2xxx_config_aneg,
                .aneg_done              = genphy_c45_aneg_done,
-               .config_init            = mv88q222x_revb0_config_init,
+               .config_init            = mv88q222x_config_init,
                .read_status            = mv88q2xxx_read_status,
                .soft_reset             = mv88q222x_soft_reset,
                .config_intr            = mv88q2xxx_config_intr,
@@ -836,7 +923,7 @@ module_phy_driver(mv88q2xxx_driver);
 
 static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
        { MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
-       { PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0), },
+       { MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK },
        { /*sentinel*/ }
 };
 MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl);
index ba319fc219571975597bf7aad3d913e77dac6898..3a9148fb1422ba5bedcbfe368fb611fc60732f66 100644 (file)
@@ -1674,6 +1674,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
        bool raw_proto = false;
        void *oiph;
        __be32 vni = 0;
+       int nh;
 
        /* Need UDP and VXLAN header to be present */
        if (!pskb_may_pull(skb, VXLAN_HLEN))
@@ -1762,12 +1763,28 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
                skb->pkt_type = PACKET_HOST;
        }
 
-       oiph = skb_network_header(skb);
+       /* Save offset of outer header relative to skb->head,
+        * because we are going to reset the network header to the inner header
+        * and might change skb->head.
+        */
+       nh = skb_network_header(skb) - skb->head;
+
        skb_reset_network_header(skb);
 
+       if (!pskb_inet_may_pull(skb)) {
+               DEV_STATS_INC(vxlan->dev, rx_length_errors);
+               DEV_STATS_INC(vxlan->dev, rx_errors);
+               vxlan_vnifilter_count(vxlan, vni, vninode,
+                                     VXLAN_VNI_STATS_RX_ERRORS, 0);
+               goto drop;
+       }
+
+       /* Get the outer header. */
+       oiph = skb->head + nh;
+
        if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
-               ++vxlan->dev->stats.rx_frame_errors;
-               ++vxlan->dev->stats.rx_errors;
+               DEV_STATS_INC(vxlan->dev, rx_frame_errors);
+               DEV_STATS_INC(vxlan->dev, rx_errors);
                vxlan_vnifilter_count(vxlan, vni, vninode,
                                      VXLAN_VNI_STATS_RX_ERRORS, 0);
                goto drop;
@@ -1837,7 +1854,9 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
                goto out;
 
        if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
-               dev->stats.tx_dropped++;
+               dev_core_stats_tx_dropped_inc(dev);
+               vxlan_vnifilter_count(vxlan, vni, NULL,
+                                     VXLAN_VNI_STATS_TX_DROPS, 0);
                goto out;
        }
        parp = arp_hdr(skb);
@@ -1893,7 +1912,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
                reply->pkt_type = PACKET_HOST;
 
                if (netif_rx(reply) == NET_RX_DROP) {
-                       dev->stats.rx_dropped++;
+                       dev_core_stats_rx_dropped_inc(dev);
                        vxlan_vnifilter_count(vxlan, vni, NULL,
                                              VXLAN_VNI_STATS_RX_DROPS, 0);
                }
@@ -2052,7 +2071,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
                        goto out;
 
                if (netif_rx(reply) == NET_RX_DROP) {
-                       dev->stats.rx_dropped++;
+                       dev_core_stats_rx_dropped_inc(dev);
                        vxlan_vnifilter_count(vxlan, vni, NULL,
                                              VXLAN_VNI_STATS_RX_DROPS, 0);
                }
@@ -2263,7 +2282,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
                                      len);
        } else {
 drop:
-               dev->stats.rx_dropped++;
+               dev_core_stats_rx_dropped_inc(dev);
                vxlan_vnifilter_count(dst_vxlan, vni, NULL,
                                      VXLAN_VNI_STATS_RX_DROPS, 0);
        }
@@ -2295,7 +2314,7 @@ static int encap_bypass_if_local(struct sk_buff *skb, struct net_device *dev,
                                           addr_family, dst_port,
                                           vxlan->cfg.flags);
                if (!dst_vxlan) {
-                       dev->stats.tx_errors++;
+                       DEV_STATS_INC(dev, tx_errors);
                        vxlan_vnifilter_count(vxlan, vni, NULL,
                                              VXLAN_VNI_STATS_TX_ERRORS, 0);
                        kfree_skb(skb);
@@ -2559,7 +2578,7 @@ out_unlock:
        return;
 
 drop:
-       dev->stats.tx_dropped++;
+       dev_core_stats_tx_dropped_inc(dev);
        vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_DROPS, 0);
        dev_kfree_skb(skb);
        return;
@@ -2567,11 +2586,11 @@ drop:
 tx_error:
        rcu_read_unlock();
        if (err == -ELOOP)
-               dev->stats.collisions++;
+               DEV_STATS_INC(dev, collisions);
        else if (err == -ENETUNREACH)
-               dev->stats.tx_carrier_errors++;
+               DEV_STATS_INC(dev, tx_carrier_errors);
        dst_release(ndst);
-       dev->stats.tx_errors++;
+       DEV_STATS_INC(dev, tx_errors);
        vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_ERRORS, 0);
        kfree_skb(skb);
 }
@@ -2604,7 +2623,7 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
        return;
 
 drop:
-       dev->stats.tx_dropped++;
+       dev_core_stats_tx_dropped_inc(dev);
        vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
                              VXLAN_VNI_STATS_TX_DROPS, 0);
        dev_kfree_skb(skb);
@@ -2642,7 +2661,7 @@ static netdev_tx_t vxlan_xmit_nhid(struct sk_buff *skb, struct net_device *dev,
        return NETDEV_TX_OK;
 
 drop:
-       dev->stats.tx_dropped++;
+       dev_core_stats_tx_dropped_inc(dev);
        vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
                              VXLAN_VNI_STATS_TX_DROPS, 0);
        dev_kfree_skb(skb);
@@ -2739,7 +2758,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
                            !is_multicast_ether_addr(eth->h_dest))
                                vxlan_fdb_miss(vxlan, eth->h_dest);
 
-                       dev->stats.tx_dropped++;
+                       dev_core_stats_tx_dropped_inc(dev);
                        vxlan_vnifilter_count(vxlan, vni, NULL,
                                              VXLAN_VNI_STATS_TX_DROPS, 0);
                        kfree_skb(skb);
index 27281a9a8951dbd53f30a27a14e0ac0be9a35c5d..095f59e7aa937aa3ae9d8e3fc3f1a25608c99f25 100644 (file)
@@ -628,27 +628,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
 }
 EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
 
-/*
- * Returns true for sink states that can't ever transition back to live.
- */
-static bool nvme_state_terminal(struct nvme_ctrl *ctrl)
-{
-       switch (nvme_ctrl_state(ctrl)) {
-       case NVME_CTRL_NEW:
-       case NVME_CTRL_LIVE:
-       case NVME_CTRL_RESETTING:
-       case NVME_CTRL_CONNECTING:
-               return false;
-       case NVME_CTRL_DELETING:
-       case NVME_CTRL_DELETING_NOIO:
-       case NVME_CTRL_DEAD:
-               return true;
-       default:
-               WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state);
-               return true;
-       }
-}
-
 /*
  * Waits for the controller state to be resetting, or returns false if it is
  * not possible to ever transition to that state.
@@ -3681,7 +3660,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
                                "Found shared namespace %d, but multipathing not supported.\n",
                                info->nsid);
                        dev_warn_once(ctrl->device,
-                               "Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0\n.");
+                               "Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0.\n");
                }
        }
 
index 5397fb428b242cea36f8c36997e134f6463e9f39..d16e976ae1a4732efef32a9da1da88be6567f621 100644 (file)
@@ -247,7 +247,8 @@ static struct nvme_ns *__nvme_find_path(struct nvme_ns_head *head, int node)
                if (nvme_path_is_disabled(ns))
                        continue;
 
-               if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA)
+               if (ns->ctrl->numa_node != NUMA_NO_NODE &&
+                   READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA)
                        distance = node_distance(node, ns->ctrl->numa_node);
                else
                        distance = LOCAL_DISTANCE;
index d0ed64dc7380e51577bc6ece92db1d0a273905a7..05532c2811774a350b169842c605c9e64b0a4daa 100644 (file)
@@ -162,6 +162,11 @@ enum nvme_quirks {
         * Disables simple suspend/resume path.
         */
        NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND      = (1 << 20),
+
+       /*
+        * MSI (but not MSI-X) interrupts are broken and never fire.
+        */
+       NVME_QUIRK_BROKEN_MSI                   = (1 << 21),
 };
 
 /*
@@ -741,6 +746,27 @@ static inline bool nvme_is_aen_req(u16 qid, __u16 command_id)
                nvme_tag_from_cid(command_id) >= NVME_AQ_BLK_MQ_DEPTH;
 }
 
+/*
+ * Returns true for sink states that can't ever transition back to live.
+ */
+static inline bool nvme_state_terminal(struct nvme_ctrl *ctrl)
+{
+       switch (nvme_ctrl_state(ctrl)) {
+       case NVME_CTRL_NEW:
+       case NVME_CTRL_LIVE:
+       case NVME_CTRL_RESETTING:
+       case NVME_CTRL_CONNECTING:
+               return false;
+       case NVME_CTRL_DELETING:
+       case NVME_CTRL_DELETING_NOIO:
+       case NVME_CTRL_DEAD:
+               return true;
+       default:
+               WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state);
+               return true;
+       }
+}
+
 void nvme_complete_rq(struct request *req);
 void nvme_complete_batch_req(struct request *req);
 
index 8e0bb9692685d4638bd21dad44fe1fbbbb147a77..710043086dffa5bdcc2e41665817760b4f3c2528 100644 (file)
@@ -1286,6 +1286,9 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
        u32 csts = readl(dev->bar + NVME_REG_CSTS);
        u8 opcode;
 
+       if (nvme_state_terminal(&dev->ctrl))
+               goto disable;
+
        /* If PCI error recovery process is happening, we cannot reset or
         * the recovery mechanism will surely fail.
         */
@@ -1390,8 +1393,11 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req)
        return BLK_EH_RESET_TIMER;
 
 disable:
-       if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING))
+       if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING)) {
+               if (nvme_state_terminal(&dev->ctrl))
+                       nvme_dev_disable(dev, true);
                return BLK_EH_DONE;
+       }
 
        nvme_dev_disable(dev, false);
        if (nvme_try_sched_reset(&dev->ctrl))
@@ -2218,6 +2224,7 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
                .priv           = dev,
        };
        unsigned int irq_queues, poll_queues;
+       unsigned int flags = PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY;
 
        /*
         * Poll queues don't need interrupts, but we need at least one I/O queue
@@ -2241,8 +2248,10 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
        irq_queues = 1;
        if (!(dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR))
                irq_queues += (nr_io_queues - poll_queues);
-       return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues,
-                             PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd);
+       if (dev->ctrl.quirks & NVME_QUIRK_BROKEN_MSI)
+               flags &= ~PCI_IRQ_MSI;
+       return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, flags,
+                                             &affd);
 }
 
 static unsigned int nvme_max_io_queues(struct nvme_dev *dev)
@@ -2471,6 +2480,7 @@ static int nvme_pci_enable(struct nvme_dev *dev)
 {
        int result = -ENOMEM;
        struct pci_dev *pdev = to_pci_dev(dev->dev);
+       unsigned int flags = PCI_IRQ_ALL_TYPES;
 
        if (pci_enable_device_mem(pdev))
                return result;
@@ -2487,7 +2497,9 @@ static int nvme_pci_enable(struct nvme_dev *dev)
         * interrupts. Pre-enable a single MSIX or MSI vec for setup. We'll
         * adjust this later.
         */
-       result = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+       if (dev->ctrl.quirks & NVME_QUIRK_BROKEN_MSI)
+               flags &= ~PCI_IRQ_MSI;
+       result = pci_alloc_irq_vectors(pdev, 1, 1, flags);
        if (result < 0)
                goto disable;
 
@@ -3384,6 +3396,8 @@ static const struct pci_device_id nvme_id_table[] = {
                .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
                                NVME_QUIRK_DISABLE_WRITE_ZEROES|
                                NVME_QUIRK_IGNORE_DEV_SUBNQN, },
+       { PCI_DEVICE(0x15b7, 0x5008),   /* Sandisk SN530 */
+               .driver_data = NVME_QUIRK_BROKEN_MSI },
        { PCI_DEVICE(0x1987, 0x5012),   /* Phison E12 */
                .driver_data = NVME_QUIRK_BOGUS_NID, },
        { PCI_DEVICE(0x1987, 0x5016),   /* Phison E16 */
index fdbcdcedcee99f064cc7258d22b7fe737d285eda..28bc2f373cfa0e715040a7d4f5a18db4690ca5dc 100644 (file)
@@ -360,12 +360,18 @@ static inline void nvme_tcp_send_all(struct nvme_tcp_queue *queue)
        } while (ret > 0);
 }
 
-static inline bool nvme_tcp_queue_more(struct nvme_tcp_queue *queue)
+static inline bool nvme_tcp_queue_has_pending(struct nvme_tcp_queue *queue)
 {
        return !list_empty(&queue->send_list) ||
                !llist_empty(&queue->req_list);
 }
 
+static inline bool nvme_tcp_queue_more(struct nvme_tcp_queue *queue)
+{
+       return !nvme_tcp_tls(&queue->ctrl->ctrl) &&
+               nvme_tcp_queue_has_pending(queue);
+}
+
 static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req,
                bool sync, bool last)
 {
@@ -386,7 +392,7 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req,
                mutex_unlock(&queue->send_mutex);
        }
 
-       if (last && nvme_tcp_queue_more(queue))
+       if (last && nvme_tcp_queue_has_pending(queue))
                queue_work_on(queue->io_cpu, nvme_tcp_wq, &queue->io_work);
 }
 
index 3ddbc3880cac8d327074fe8f923b9f257979c8bd..4f08362aee8b001f958f85a4fadf7c3d8621bee0 100644 (file)
@@ -285,9 +285,9 @@ int nvmet_auth_host_hash(struct nvmet_req *req, u8 *response,
        }
 
        if (shash_len != crypto_shash_digestsize(shash_tfm)) {
-               pr_debug("%s: hash len mismatch (len %d digest %d)\n",
-                        __func__, shash_len,
-                        crypto_shash_digestsize(shash_tfm));
+               pr_err("%s: hash len mismatch (len %d digest %d)\n",
+                       __func__, shash_len,
+                       crypto_shash_digestsize(shash_tfm));
                ret = -EINVAL;
                goto out_free_tfm;
        }
@@ -370,7 +370,7 @@ out_free_response:
        nvme_auth_free_key(transformed_key);
 out_free_tfm:
        crypto_free_shash(shash_tfm);
-       return 0;
+       return ret;
 }
 
 int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
@@ -480,7 +480,7 @@ out_free_response:
        nvme_auth_free_key(transformed_key);
 out_free_tfm:
        crypto_free_shash(shash_tfm);
-       return 0;
+       return ret;
 }
 
 int nvmet_auth_ctrl_exponential(struct nvmet_req *req,
index a2325330bf22145202837aa5cf89d9ec6543ab59..7fda69395c1ef80d319d5cefa70e6d5525db9bb3 100644 (file)
@@ -754,6 +754,18 @@ static struct configfs_attribute *nvmet_ns_attrs[] = {
        NULL,
 };
 
+bool nvmet_subsys_nsid_exists(struct nvmet_subsys *subsys, u32 nsid)
+{
+       struct config_item *ns_item;
+       char name[12];
+
+       snprintf(name, sizeof(name), "%u", nsid);
+       mutex_lock(&subsys->namespaces_group.cg_subsys->su_mutex);
+       ns_item = config_group_find_item(&subsys->namespaces_group, name);
+       mutex_unlock(&subsys->namespaces_group.cg_subsys->su_mutex);
+       return ns_item != NULL;
+}
+
 static void nvmet_ns_release(struct config_item *item)
 {
        struct nvmet_ns *ns = to_nvmet_ns(item);
index 8860a3eb71ec891e948a34060f34b4b148553418..2fde22323622e44366e6a194eb9af028799014e3 100644 (file)
@@ -437,10 +437,13 @@ void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl)
 u16 nvmet_req_find_ns(struct nvmet_req *req)
 {
        u32 nsid = le32_to_cpu(req->cmd->common.nsid);
+       struct nvmet_subsys *subsys = nvmet_req_subsys(req);
 
-       req->ns = xa_load(&nvmet_req_subsys(req)->namespaces, nsid);
+       req->ns = xa_load(&subsys->namespaces, nsid);
        if (unlikely(!req->ns)) {
                req->error_loc = offsetof(struct nvme_common_command, nsid);
+               if (nvmet_subsys_nsid_exists(subsys, nsid))
+                       return NVME_SC_INTERNAL_PATH_ERROR;
                return NVME_SC_INVALID_NS | NVME_SC_DNR;
        }
 
@@ -1683,7 +1686,8 @@ static int __init nvmet_init(void)
        if (!buffered_io_wq)
                goto out_free_zbd_work_queue;
 
-       nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
+       nvmet_wq = alloc_workqueue("nvmet-wq",
+                       WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
        if (!nvmet_wq)
                goto out_free_buffered_work_queue;
 
index f460728e1df1fd87e24969e782203c7684a23326..c1306de1f4ddf650c2ee66167559f27e4004e837 100644 (file)
@@ -543,6 +543,7 @@ void nvmet_subsys_disc_changed(struct nvmet_subsys *subsys,
                struct nvmet_host *host);
 void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
                u8 event_info, u8 log_page);
+bool nvmet_subsys_nsid_exists(struct nvmet_subsys *subsys, u32 nsid);
 
 #define NVMET_MIN_QUEUE_SIZE   16
 #define NVMET_MAX_QUEUE_SIZE   1024
index 5b8c63e74639d7485fe7feedf514e06d7e7c1d4e..6e1b4140cde072c75c561143550feadef8a9b563 100644 (file)
@@ -474,12 +474,8 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue)
        return 0;
 
 out_free:
-       while (--i >= 0) {
-               struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
-
-               list_del(&rsp->free_list);
-               nvmet_rdma_free_rsp(ndev, rsp);
-       }
+       while (--i >= 0)
+               nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
        kfree(queue->rsps);
 out:
        return ret;
@@ -490,12 +486,8 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue)
        struct nvmet_rdma_device *ndev = queue->dev;
        int i, nr_rsps = queue->recv_queue_size * 2;
 
-       for (i = 0; i < nr_rsps; i++) {
-               struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
-
-               list_del(&rsp->free_list);
-               nvmet_rdma_free_rsp(ndev, rsp);
-       }
+       for (i = 0; i < nr_rsps; i++)
+               nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
        kfree(queue->rsps);
 }
 
index a5422e2c979addca1f219777b47f61f5817e302a..380f22ee3ebba3ef5fe50108b39ea78345c1f1ba 100644 (file)
@@ -348,6 +348,7 @@ static int nvmet_tcp_check_ddgst(struct nvmet_tcp_queue *queue, void *pdu)
        return 0;
 }
 
+/* If cmd buffers are NULL, no operation is performed */
 static void nvmet_tcp_free_cmd_buffers(struct nvmet_tcp_cmd *cmd)
 {
        kfree(cmd->iov);
@@ -1581,13 +1582,9 @@ static void nvmet_tcp_free_cmd_data_in_buffers(struct nvmet_tcp_queue *queue)
        struct nvmet_tcp_cmd *cmd = queue->cmds;
        int i;
 
-       for (i = 0; i < queue->nr_cmds; i++, cmd++) {
-               if (nvmet_tcp_need_data_in(cmd))
-                       nvmet_tcp_free_cmd_buffers(cmd);
-       }
-
-       if (!queue->nr_cmds && nvmet_tcp_need_data_in(&queue->connect))
-               nvmet_tcp_free_cmd_buffers(&queue->connect);
+       for (i = 0; i < queue->nr_cmds; i++, cmd++)
+               nvmet_tcp_free_cmd_buffers(cmd);
+       nvmet_tcp_free_cmd_buffers(&queue->connect);
 }
 
 static void nvmet_tcp_release_queue_work(struct work_struct *w)
index a6358ee99b74b99a90df38c63e08943b628a7b80..769ae2cf5f3cc7af103287c2143c486fd8fb9f88 100644 (file)
@@ -1252,6 +1252,7 @@ DEFINE_SIMPLE_PROP(backlight, "backlight", NULL)
 DEFINE_SIMPLE_PROP(panel, "panel", NULL)
 DEFINE_SIMPLE_PROP(msi_parent, "msi-parent", "#msi-cells")
 DEFINE_SIMPLE_PROP(post_init_providers, "post-init-providers", NULL)
+DEFINE_SIMPLE_PROP(access_controllers, "access-controllers", "#access-controller-cells")
 DEFINE_SUFFIX_PROP(regulators, "-supply", NULL)
 DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells")
 
@@ -1359,6 +1360,7 @@ static const struct supplier_bindings of_supplier_bindings[] = {
        { .parse_prop = parse_msi_parent, },
        { .parse_prop = parse_gpio_compat, },
        { .parse_prop = parse_interrupts, },
+       { .parse_prop = parse_access_controllers, },
        { .parse_prop = parse_regulators, },
        { .parse_prop = parse_gpio, },
        { .parse_prop = parse_gpios, },
index 2428d278e015ab99b2989b01a6762806cebb549b..47761c7ef267ab984fe93638eb7f2f485c119064 100644 (file)
@@ -177,8 +177,8 @@ void pci_restore_aspm_l1ss_state(struct pci_dev *pdev)
        /* Restore L0s/L1 if they were enabled */
        if (FIELD_GET(PCI_EXP_LNKCTL_ASPMC, clnkctl) ||
            FIELD_GET(PCI_EXP_LNKCTL_ASPMC, plnkctl)) {
-               pcie_capability_write_word(parent, PCI_EXP_LNKCTL, clnkctl);
-               pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, plnkctl);
+               pcie_capability_write_word(parent, PCI_EXP_LNKCTL, plnkctl);
+               pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, clnkctl);
        }
 }
 
index d45657aa986ae9c013504fbba6497685277ae3bd..7e4f93a3bc7ac9bcafc92ddb795569d7cca6474d 100644 (file)
@@ -235,13 +235,13 @@ config PINCTRL_INGENIC
 
 config PINCTRL_K210
        bool "Pinctrl driver for the Canaan Kendryte K210 SoC"
-       depends on RISCV && SOC_CANAAN && OF
+       depends on RISCV && SOC_CANAAN_K210 && OF
        select GENERIC_PINMUX_FUNCTIONS
        select GENERIC_PINCONF
        select GPIOLIB
        select OF_GPIO
        select REGMAP_MMIO
-       default SOC_CANAAN
+       default SOC_CANAAN_K210
        help
          Add support for the Canaan Kendryte K210 RISC-V SOC Field
          Programmable IO Array (FPIOA) controller.
@@ -450,6 +450,17 @@ config PINCTRL_ROCKCHIP
        help
           This support pinctrl and GPIO driver for Rockchip SoCs.
 
+config PINCTRL_SCMI
+       tristate "Pinctrl driver using SCMI protocol interface"
+       depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+       select PINMUX
+       select GENERIC_PINCONF
+       help
+         This driver provides support for pinctrl which is controlled
+         by firmware that implements the SCMI interface.
+         It uses SCMI Message Protocol to interact with the
+         firmware providing all the pinctrl controls.
+
 config PINCTRL_SINGLE
        tristate "One-register-per-pin type device tree based pinctrl driver"
        depends on OF
index 2152539b53d54cf45fe169fe31a49a36ea56e416..cc809669405ab6c6905fe0b2380f91b211a2d470 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_PINCTRL_PIC32)   += pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)        += pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_RK805)    += pinctrl-rk805.o
 obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
+obj-$(CONFIG_PINCTRL_SCMI)     += pinctrl-scmi.o
 obj-$(CONFIG_PINCTRL_SINGLE)   += pinctrl-single.o
 obj-$(CONFIG_PINCTRL_ST)       += pinctrl-st.o
 obj-$(CONFIG_PINCTRL_STMFX)    += pinctrl-stmfx.o
index d376fa7114d1a024d63eba168a6809f0816acfba..029efe16f8cc29d04942ef4f420c37a25dc2f4b3 100644 (file)
@@ -43,7 +43,7 @@
 #define SCU614         0x614 /* Disable GPIO Internal Pull-Down #1 */
 #define SCU618         0x618 /* Disable GPIO Internal Pull-Down #2 */
 #define SCU61C         0x61c /* Disable GPIO Internal Pull-Down #3 */
-#define SCU620         0x620 /* Disable GPIO Internal Pull-Down #4 */
+#define SCU630         0x630 /* Disable GPIO Internal Pull-Down #4 */
 #define SCU634         0x634 /* Disable GPIO Internal Pull-Down #5 */
 #define SCU638         0x638 /* Disable GPIO Internal Pull-Down #6 */
 #define SCU690         0x690 /* Multi-function Pin Control #24 */
@@ -2495,38 +2495,38 @@ static struct aspeed_pin_config aspeed_g6_configs[] = {
        ASPEED_PULL_DOWN_PINCONF(D14, SCU61C, 0),
 
        /* GPIOS7 */
-       ASPEED_PULL_DOWN_PINCONF(T24, SCU620, 23),
+       ASPEED_PULL_DOWN_PINCONF(T24, SCU630, 23),
        /* GPIOS6 */
-       ASPEED_PULL_DOWN_PINCONF(P23, SCU620, 22),
+       ASPEED_PULL_DOWN_PINCONF(P23, SCU630, 22),
        /* GPIOS5 */
-       ASPEED_PULL_DOWN_PINCONF(P24, SCU620, 21),
+       ASPEED_PULL_DOWN_PINCONF(P24, SCU630, 21),
        /* GPIOS4 */
-       ASPEED_PULL_DOWN_PINCONF(R26, SCU620, 20),
+       ASPEED_PULL_DOWN_PINCONF(R26, SCU630, 20),
        /* GPIOS3*/
-       ASPEED_PULL_DOWN_PINCONF(R24, SCU620, 19),
+       ASPEED_PULL_DOWN_PINCONF(R24, SCU630, 19),
        /* GPIOS2 */
-       ASPEED_PULL_DOWN_PINCONF(T26, SCU620, 18),
+       ASPEED_PULL_DOWN_PINCONF(T26, SCU630, 18),
        /* GPIOS1 */
-       ASPEED_PULL_DOWN_PINCONF(T25, SCU620, 17),
+       ASPEED_PULL_DOWN_PINCONF(T25, SCU630, 17),
        /* GPIOS0 */
-       ASPEED_PULL_DOWN_PINCONF(R23, SCU620, 16),
+       ASPEED_PULL_DOWN_PINCONF(R23, SCU630, 16),
 
        /* GPIOR7 */
-       ASPEED_PULL_DOWN_PINCONF(U26, SCU620, 15),
+       ASPEED_PULL_DOWN_PINCONF(U26, SCU630, 15),
        /* GPIOR6 */
-       ASPEED_PULL_DOWN_PINCONF(W26, SCU620, 14),
+       ASPEED_PULL_DOWN_PINCONF(W26, SCU630, 14),
        /* GPIOR5 */
-       ASPEED_PULL_DOWN_PINCONF(T23, SCU620, 13),
+       ASPEED_PULL_DOWN_PINCONF(T23, SCU630, 13),
        /* GPIOR4 */
-       ASPEED_PULL_DOWN_PINCONF(U25, SCU620, 12),
+       ASPEED_PULL_DOWN_PINCONF(U25, SCU630, 12),
        /* GPIOR3*/
-       ASPEED_PULL_DOWN_PINCONF(V26, SCU620, 11),
+       ASPEED_PULL_DOWN_PINCONF(V26, SCU630, 11),
        /* GPIOR2 */
-       ASPEED_PULL_DOWN_PINCONF(V24, SCU620, 10),
+       ASPEED_PULL_DOWN_PINCONF(V24, SCU630, 10),
        /* GPIOR1 */
-       ASPEED_PULL_DOWN_PINCONF(U24, SCU620, 9),
+       ASPEED_PULL_DOWN_PINCONF(U24, SCU630, 9),
        /* GPIOR0 */
-       ASPEED_PULL_DOWN_PINCONF(V25, SCU620, 8),
+       ASPEED_PULL_DOWN_PINCONF(V25, SCU630, 8),
 
        /* GPIOX7 */
        ASPEED_PULL_DOWN_PINCONF(AB10, SCU634, 31),
index 6649357637ff337dc49c4e522287d2366dc36516..cffeb869130ddab486fb2ce00e4c1d5a27575875 100644 (file)
@@ -2124,13 +2124,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
 
        error = pinctrl_claim_hogs(pctldev);
        if (error) {
-               dev_err(pctldev->dev, "could not claim hogs: %i\n",
-                       error);
-               pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
-                                     pctldev->desc->npins);
-               mutex_destroy(&pctldev->mutex);
-               kfree(pctldev);
-
+               dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
                return error;
        }
 
index df1efc2e5202591d5f9f23d95f6008853b91e046..6a94ecd6a8deaeb6b7fc14c6387987f52ead306a 100644 (file)
@@ -220,14 +220,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
        for (state = 0; ; state++) {
                /* Retrieve the pinctrl-* property */
                propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
-               if (!propname)
-                       return -ENOMEM;
+               if (!propname) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
                prop = of_find_property(np, propname, &size);
                kfree(propname);
                if (!prop) {
                        if (state == 0) {
-                               of_node_put(np);
-                               return -ENODEV;
+                               ret = -ENODEV;
+                               goto err;
                        }
                        break;
                }
index ac97724c59bae9705e89c93246ec3f09580d663d..4e87f5b875c0e8f7089b9411c9b1610eaa2a8b9a 100644 (file)
@@ -231,6 +231,7 @@ static const unsigned int byt_score_pins_map[BYT_NGPIO_SCORE] = {
 /* SCORE groups */
 static const unsigned int byt_score_uart1_pins[] = { 70, 71, 72, 73 };
 static const unsigned int byt_score_uart2_pins[] = { 74, 75, 76, 77 };
+static const unsigned int byt_score_uart3_pins[] = { 57, 61 };
 
 static const unsigned int byt_score_pwm0_pins[] = { 94 };
 static const unsigned int byt_score_pwm1_pins[] = { 95 };
@@ -278,37 +279,38 @@ static const unsigned int byt_score_plt_clk5_pins[] = { 101 };
 static const unsigned int byt_score_smbus_pins[] = { 51, 52, 53 };
 
 static const struct intel_pingroup byt_score_groups[] = {
-       PIN_GROUP("uart1_grp", byt_score_uart1_pins, 1),
-       PIN_GROUP("uart2_grp", byt_score_uart2_pins, 1),
-       PIN_GROUP("pwm0_grp", byt_score_pwm0_pins, 1),
-       PIN_GROUP("pwm1_grp", byt_score_pwm1_pins, 1),
-       PIN_GROUP("ssp2_grp", byt_score_ssp2_pins, 1),
-       PIN_GROUP("sio_spi_grp", byt_score_sio_spi_pins, 1),
-       PIN_GROUP("i2c5_grp", byt_score_i2c5_pins, 1),
-       PIN_GROUP("i2c6_grp", byt_score_i2c6_pins, 1),
-       PIN_GROUP("i2c4_grp", byt_score_i2c4_pins, 1),
-       PIN_GROUP("i2c3_grp", byt_score_i2c3_pins, 1),
-       PIN_GROUP("i2c2_grp", byt_score_i2c2_pins, 1),
-       PIN_GROUP("i2c1_grp", byt_score_i2c1_pins, 1),
-       PIN_GROUP("i2c0_grp", byt_score_i2c0_pins, 1),
-       PIN_GROUP("ssp0_grp", byt_score_ssp0_pins, 1),
-       PIN_GROUP("ssp1_grp", byt_score_ssp1_pins, 1),
-       PIN_GROUP("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
-       PIN_GROUP("sdio_grp", byt_score_sdio_pins, 1),
-       PIN_GROUP("emmc_grp", byt_score_emmc_pins, 1),
-       PIN_GROUP("lpc_grp", byt_score_ilb_lpc_pins, 1),
-       PIN_GROUP("sata_grp", byt_score_sata_pins, 1),
-       PIN_GROUP("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
-       PIN_GROUP("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
-       PIN_GROUP("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
-       PIN_GROUP("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
-       PIN_GROUP("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
-       PIN_GROUP("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
-       PIN_GROUP("smbus_grp", byt_score_smbus_pins, 1),
+       PIN_GROUP_GPIO("uart1_grp", byt_score_uart1_pins, 1),
+       PIN_GROUP_GPIO("uart2_grp", byt_score_uart2_pins, 1),
+       PIN_GROUP_GPIO("uart3_grp", byt_score_uart3_pins, 1),
+       PIN_GROUP_GPIO("pwm0_grp", byt_score_pwm0_pins, 1),
+       PIN_GROUP_GPIO("pwm1_grp", byt_score_pwm1_pins, 1),
+       PIN_GROUP_GPIO("ssp2_grp", byt_score_ssp2_pins, 1),
+       PIN_GROUP_GPIO("sio_spi_grp", byt_score_sio_spi_pins, 1),
+       PIN_GROUP_GPIO("i2c5_grp", byt_score_i2c5_pins, 1),
+       PIN_GROUP_GPIO("i2c6_grp", byt_score_i2c6_pins, 1),
+       PIN_GROUP_GPIO("i2c4_grp", byt_score_i2c4_pins, 1),
+       PIN_GROUP_GPIO("i2c3_grp", byt_score_i2c3_pins, 1),
+       PIN_GROUP_GPIO("i2c2_grp", byt_score_i2c2_pins, 1),
+       PIN_GROUP_GPIO("i2c1_grp", byt_score_i2c1_pins, 1),
+       PIN_GROUP_GPIO("i2c0_grp", byt_score_i2c0_pins, 1),
+       PIN_GROUP_GPIO("ssp0_grp", byt_score_ssp0_pins, 1),
+       PIN_GROUP_GPIO("ssp1_grp", byt_score_ssp1_pins, 1),
+       PIN_GROUP_GPIO("sdcard_grp", byt_score_sdcard_pins, byt_score_sdcard_mux_values),
+       PIN_GROUP_GPIO("sdio_grp", byt_score_sdio_pins, 1),
+       PIN_GROUP_GPIO("emmc_grp", byt_score_emmc_pins, 1),
+       PIN_GROUP_GPIO("lpc_grp", byt_score_ilb_lpc_pins, 1),
+       PIN_GROUP_GPIO("sata_grp", byt_score_sata_pins, 1),
+       PIN_GROUP_GPIO("plt_clk0_grp", byt_score_plt_clk0_pins, 1),
+       PIN_GROUP_GPIO("plt_clk1_grp", byt_score_plt_clk1_pins, 1),
+       PIN_GROUP_GPIO("plt_clk2_grp", byt_score_plt_clk2_pins, 1),
+       PIN_GROUP_GPIO("plt_clk3_grp", byt_score_plt_clk3_pins, 1),
+       PIN_GROUP_GPIO("plt_clk4_grp", byt_score_plt_clk4_pins, 1),
+       PIN_GROUP_GPIO("plt_clk5_grp", byt_score_plt_clk5_pins, 1),
+       PIN_GROUP_GPIO("smbus_grp", byt_score_smbus_pins, 1),
 };
 
 static const char * const byt_score_uart_groups[] = {
-       "uart1_grp", "uart2_grp",
+       "uart1_grp", "uart2_grp", "uart3_grp",
 };
 static const char * const byt_score_pwm_groups[] = {
        "pwm0_grp", "pwm1_grp",
@@ -332,12 +334,14 @@ static const char * const byt_score_plt_clk_groups[] = {
 };
 static const char * const byt_score_smbus_groups[] = { "smbus_grp" };
 static const char * const byt_score_gpio_groups[] = {
-       "uart1_grp", "uart2_grp", "pwm0_grp", "pwm1_grp", "ssp0_grp",
-       "ssp1_grp", "ssp2_grp", "sio_spi_grp", "i2c0_grp", "i2c1_grp",
-       "i2c2_grp", "i2c3_grp", "i2c4_grp", "i2c5_grp", "i2c6_grp",
-       "sdcard_grp", "sdio_grp", "emmc_grp", "lpc_grp", "sata_grp",
-       "plt_clk0_grp", "plt_clk1_grp", "plt_clk2_grp", "plt_clk3_grp",
-       "plt_clk4_grp", "plt_clk5_grp", "smbus_grp",
+       "uart1_grp_gpio", "uart2_grp_gpio", "uart3_grp_gpio", "pwm0_grp_gpio",
+       "pwm1_grp_gpio", "ssp0_grp_gpio", "ssp1_grp_gpio", "ssp2_grp_gpio",
+       "sio_spi_grp_gpio", "i2c0_grp_gpio", "i2c1_grp_gpio", "i2c2_grp_gpio",
+       "i2c3_grp_gpio", "i2c4_grp_gpio", "i2c5_grp_gpio", "i2c6_grp_gpio",
+       "sdcard_grp_gpio", "sdio_grp_gpio", "emmc_grp_gpio", "lpc_grp_gpio",
+       "sata_grp_gpio", "plt_clk0_grp_gpio", "plt_clk1_grp_gpio",
+       "plt_clk2_grp_gpio", "plt_clk3_grp_gpio", "plt_clk4_grp_gpio",
+       "plt_clk5_grp_gpio", "smbus_grp_gpio",
 };
 
 static const struct intel_function byt_score_functions[] = {
@@ -456,8 +460,8 @@ static const struct intel_pingroup byt_sus_groups[] = {
        PIN_GROUP("usb_oc_grp_gpio", byt_sus_usb_over_current_pins, byt_sus_usb_over_current_gpio_mode_values),
        PIN_GROUP("usb_ulpi_grp_gpio", byt_sus_usb_ulpi_pins, byt_sus_usb_ulpi_gpio_mode_values),
        PIN_GROUP("pcu_spi_grp_gpio", byt_sus_pcu_spi_pins, byt_sus_pcu_spi_gpio_mode_values),
-       PIN_GROUP("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
-       PIN_GROUP("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
+       PIN_GROUP_GPIO("pmu_clk1_grp", byt_sus_pmu_clk1_pins, 1),
+       PIN_GROUP_GPIO("pmu_clk2_grp", byt_sus_pmu_clk2_pins, 1),
 };
 
 static const char * const byt_sus_usb_groups[] = {
@@ -469,7 +473,7 @@ static const char * const byt_sus_pmu_clk_groups[] = {
 };
 static const char * const byt_sus_gpio_groups[] = {
        "usb_oc_grp_gpio", "usb_ulpi_grp_gpio", "pcu_spi_grp_gpio",
-       "pmu_clk1_grp", "pmu_clk2_grp",
+       "pmu_clk1_grp_gpio", "pmu_clk2_grp_gpio",
 };
 
 static const struct intel_function byt_sus_functions[] = {
index fde65e18cd145ecb1eb809f87ecec289067e44e8..6981e2fab93f34998b737ac39446c4eed5646923 100644 (file)
@@ -179,6 +179,10 @@ struct intel_community {
                .modes = __builtin_choose_expr(__builtin_constant_p((m)), NULL, (m)),   \
        }
 
+#define PIN_GROUP_GPIO(n, p, m)                                                \
+        PIN_GROUP(n, p, m),                                            \
+        PIN_GROUP(n "_gpio", p, 0)
+
 #define FUNCTION(n, g)                                                 \
        {                                                               \
                .func = PINCTRL_PINFUNCTION((n), (g), ARRAY_SIZE(g)),   \
index b6bc31abd2b068695dcfd5025c0f31ea0b3c679e..b19bc391705ee079939f34ab03d554160d97c234 100644 (file)
@@ -165,20 +165,21 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
                err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
                break;
        case PIN_CONFIG_INPUT_ENABLE:
-       case PIN_CONFIG_OUTPUT_ENABLE:
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret);
+               if (!ret)
+                       err = -EINVAL;
+               break;
+       case PIN_CONFIG_OUTPUT:
                err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
                if (err)
                        break;
-               /*     CONFIG     Current direction return value
-                * -------------  ----------------- ----------------------
-                * OUTPUT_ENABLE       output       1 (= HW value)
-                *                     input        0 (= HW value)
-                * INPUT_ENABLE        output       0 (= reverse HW value)
-                *                     input        1 (= reverse HW value)
-                */
-               if (param == PIN_CONFIG_INPUT_ENABLE)
-                       ret = !ret;
 
+               if (!ret) {
+                       err = -EINVAL;
+                       break;
+               }
+
+               err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret);
                break;
        case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
                err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
@@ -193,6 +194,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
                }
 
                err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
+               if (!ret)
+                       err = -EINVAL;
                break;
        case PIN_CONFIG_DRIVE_STRENGTH:
                if (!hw->soc->drive_get)
@@ -281,26 +284,9 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
                        break;
                err = hw->soc->bias_set_combo(hw, desc, 0, arg);
                break;
-       case PIN_CONFIG_OUTPUT_ENABLE:
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
-                                      MTK_DISABLE);
-               /* Keep set direction to consider the case that a GPIO pin
-                *  does not have SMT control
-                */
-               if (err != -ENOTSUPP)
-                       break;
-
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
-                                      MTK_OUTPUT);
-               break;
        case PIN_CONFIG_INPUT_ENABLE:
                /* regard all non-zero value as enable */
                err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
-               if (err)
-                       break;
-
-               err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
-                                      MTK_INPUT);
                break;
        case PIN_CONFIG_SLEW_RATE:
                /* regard all non-zero value as enable */
index 79f5d753d7e1a53df0da9bb0446bf8fdfbd3042c..50a87d9618a8e8e078424db33c7e13a7c7ed1dc6 100644 (file)
@@ -250,7 +250,7 @@ static const unsigned int pdm_dclk_x_pins[]         = { GPIOX_10 };
 static const unsigned int pdm_din2_a_pins[]            = { GPIOA_6 };
 static const unsigned int pdm_din1_a_pins[]            = { GPIOA_7 };
 static const unsigned int pdm_din0_a_pins[]            = { GPIOA_8 };
-static const unsigned int pdm_dclk_pins[]              = { GPIOA_9 };
+static const unsigned int pdm_dclk_a_pins[]            = { GPIOA_9 };
 
 /* gen_clk */
 static const unsigned int gen_clk_x_pins[]             = { GPIOX_7 };
@@ -591,7 +591,7 @@ static struct meson_pmx_group meson_a1_periphs_groups[] = {
        GROUP(pdm_din2_a,               3),
        GROUP(pdm_din1_a,               3),
        GROUP(pdm_din0_a,               3),
-       GROUP(pdm_dclk,                 3),
+       GROUP(pdm_dclk_a,               3),
        GROUP(pwm_c_a,                  3),
        GROUP(pwm_b_a,                  3),
 
@@ -755,7 +755,7 @@ static const char * const spi_a_groups[] = {
 
 static const char * const pdm_groups[] = {
        "pdm_din0_x", "pdm_din1_x", "pdm_din2_x", "pdm_dclk_x", "pdm_din2_a",
-       "pdm_din1_a", "pdm_din0_a", "pdm_dclk",
+       "pdm_din1_a", "pdm_din0_a", "pdm_dclk_a",
 };
 
 static const char * const gen_clk_groups[] = {
diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c
new file mode 100644 (file)
index 0000000..036bc1e
--- /dev/null
@@ -0,0 +1,571 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Power Interface (SCMI) Protocol based pinctrl driver
+ *
+ * Copyright (C) 2024 EPAM
+ * Copyright 2024 NXP
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/scmi_protocol.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include "pinctrl-utils.h"
+#include "core.h"
+#include "pinconf.h"
+
+#define DRV_NAME "scmi-pinctrl"
+
+/* Define num configs, if not large than 4 use stack, else use kcalloc() */
+#define SCMI_NUM_CONFIGS       4
+
+static const struct scmi_pinctrl_proto_ops *pinctrl_ops;
+
+struct scmi_pinctrl {
+       struct device *dev;
+       struct scmi_protocol_handle *ph;
+       struct pinctrl_dev *pctldev;
+       struct pinctrl_desc pctl_desc;
+       struct pinfunction *functions;
+       unsigned int nr_functions;
+       struct pinctrl_pin_desc *pins;
+       unsigned int nr_pins;
+};
+
+static int pinctrl_scmi_get_groups_count(struct pinctrl_dev *pctldev)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->count_get(pmx->ph, GROUP_TYPE);
+}
+
+static const char *pinctrl_scmi_get_group_name(struct pinctrl_dev *pctldev,
+                                              unsigned int selector)
+{
+       int ret;
+       const char *name;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       ret = pinctrl_ops->name_get(pmx->ph, selector, GROUP_TYPE, &name);
+       if (ret) {
+               dev_err(pmx->dev, "get name failed with err %d", ret);
+               return NULL;
+       }
+
+       return name;
+}
+
+static int pinctrl_scmi_get_group_pins(struct pinctrl_dev *pctldev,
+                                      unsigned int selector,
+                                      const unsigned int **pins,
+                                      unsigned int *num_pins)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->group_pins_get(pmx->ph, selector, pins, num_pins);
+}
+
+static const struct pinctrl_ops pinctrl_scmi_pinctrl_ops = {
+       .get_groups_count = pinctrl_scmi_get_groups_count,
+       .get_group_name = pinctrl_scmi_get_group_name,
+       .get_group_pins = pinctrl_scmi_get_group_pins,
+#ifdef CONFIG_OF
+       .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+       .dt_free_map = pinconf_generic_dt_free_map,
+#endif
+};
+
+static int pinctrl_scmi_get_functions_count(struct pinctrl_dev *pctldev)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->count_get(pmx->ph, FUNCTION_TYPE);
+}
+
+static const char *pinctrl_scmi_get_function_name(struct pinctrl_dev *pctldev,
+                                                 unsigned int selector)
+{
+       int ret;
+       const char *name;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       ret = pinctrl_ops->name_get(pmx->ph, selector, FUNCTION_TYPE, &name);
+       if (ret) {
+               dev_err(pmx->dev, "get name failed with err %d", ret);
+               return NULL;
+       }
+
+       return name;
+}
+
+static int pinctrl_scmi_get_function_groups(struct pinctrl_dev *pctldev,
+                                           unsigned int selector,
+                                           const char * const **p_groups,
+                                           unsigned int * const p_num_groups)
+{
+       struct pinfunction *func;
+       const unsigned int *group_ids;
+       unsigned int num_groups;
+       const char **groups;
+       int ret, i;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       if (!p_groups || !p_num_groups)
+               return -EINVAL;
+
+       if (selector >= pmx->nr_functions)
+               return -EINVAL;
+
+       func = &pmx->functions[selector];
+       if (func->ngroups)
+               goto done;
+
+       ret = pinctrl_ops->function_groups_get(pmx->ph, selector, &num_groups,
+                                              &group_ids);
+       if (ret) {
+               dev_err(pmx->dev, "Unable to get function groups, err %d", ret);
+               return ret;
+       }
+       if (!num_groups)
+               return -EINVAL;
+
+       groups = kcalloc(num_groups, sizeof(*groups), GFP_KERNEL);
+       if (!groups)
+               return -ENOMEM;
+
+       for (i = 0; i < num_groups; i++) {
+               groups[i] = pinctrl_scmi_get_group_name(pctldev, group_ids[i]);
+               if (!groups[i]) {
+                       ret = -EINVAL;
+                       goto err_free;
+               }
+       }
+
+       func->ngroups = num_groups;
+       func->groups = groups;
+done:
+       *p_groups = func->groups;
+       *p_num_groups = func->ngroups;
+
+       return 0;
+
+err_free:
+       kfree(groups);
+
+       return ret;
+}
+
+static int pinctrl_scmi_func_set_mux(struct pinctrl_dev *pctldev,
+                                    unsigned int selector, unsigned int group)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->mux_set(pmx->ph, selector, group);
+}
+
+static int pinctrl_scmi_request(struct pinctrl_dev *pctldev,
+                               unsigned int offset)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->pin_request(pmx->ph, offset);
+}
+
+static int pinctrl_scmi_free(struct pinctrl_dev *pctldev, unsigned int offset)
+{
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+       return pinctrl_ops->pin_free(pmx->ph, offset);
+}
+
+static const struct pinmux_ops pinctrl_scmi_pinmux_ops = {
+       .request = pinctrl_scmi_request,
+       .free = pinctrl_scmi_free,
+       .get_functions_count = pinctrl_scmi_get_functions_count,
+       .get_function_name = pinctrl_scmi_get_function_name,
+       .get_function_groups = pinctrl_scmi_get_function_groups,
+       .set_mux = pinctrl_scmi_func_set_mux,
+};
+
+static int pinctrl_scmi_map_pinconf_type(enum pin_config_param param,
+                                        enum scmi_pinctrl_conf_type *type)
+{
+       u32 arg = param;
+
+       switch (arg) {
+       case PIN_CONFIG_BIAS_BUS_HOLD:
+               *type = SCMI_PIN_BIAS_BUS_HOLD;
+               break;
+       case PIN_CONFIG_BIAS_DISABLE:
+               *type = SCMI_PIN_BIAS_DISABLE;
+               break;
+       case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
+               *type = SCMI_PIN_BIAS_HIGH_IMPEDANCE;
+               break;
+       case PIN_CONFIG_BIAS_PULL_DOWN:
+               *type = SCMI_PIN_BIAS_PULL_DOWN;
+               break;
+       case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
+               *type = SCMI_PIN_BIAS_PULL_DEFAULT;
+               break;
+       case PIN_CONFIG_BIAS_PULL_UP:
+               *type = SCMI_PIN_BIAS_PULL_UP;
+               break;
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               *type = SCMI_PIN_DRIVE_OPEN_DRAIN;
+               break;
+       case PIN_CONFIG_DRIVE_OPEN_SOURCE:
+               *type = SCMI_PIN_DRIVE_OPEN_SOURCE;
+               break;
+       case PIN_CONFIG_DRIVE_PUSH_PULL:
+               *type = SCMI_PIN_DRIVE_PUSH_PULL;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH:
+               *type = SCMI_PIN_DRIVE_STRENGTH;
+               break;
+       case PIN_CONFIG_DRIVE_STRENGTH_UA:
+               *type = SCMI_PIN_DRIVE_STRENGTH;
+               break;
+       case PIN_CONFIG_INPUT_DEBOUNCE:
+               *type = SCMI_PIN_INPUT_DEBOUNCE;
+               break;
+       case PIN_CONFIG_INPUT_ENABLE:
+               *type = SCMI_PIN_INPUT_MODE;
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT:
+               *type = SCMI_PIN_INPUT_SCHMITT;
+               break;
+       case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+               *type = SCMI_PIN_INPUT_MODE;
+               break;
+       case PIN_CONFIG_MODE_LOW_POWER:
+               *type = SCMI_PIN_LOW_POWER_MODE;
+               break;
+       case PIN_CONFIG_OUTPUT:
+               *type = SCMI_PIN_OUTPUT_VALUE;
+               break;
+       case PIN_CONFIG_OUTPUT_ENABLE:
+               *type = SCMI_PIN_OUTPUT_MODE;
+               break;
+       case PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS:
+               *type = SCMI_PIN_OUTPUT_VALUE;
+               break;
+       case PIN_CONFIG_POWER_SOURCE:
+               *type = SCMI_PIN_POWER_SOURCE;
+               break;
+       case PIN_CONFIG_SLEW_RATE:
+               *type = SCMI_PIN_SLEW_RATE;
+               break;
+       case SCMI_PIN_OEM_START ... SCMI_PIN_OEM_END:
+               *type = arg;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int pinctrl_scmi_pinconf_get(struct pinctrl_dev *pctldev,
+                                   unsigned int pin, unsigned long *config)
+{
+       int ret;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param config_type;
+       enum scmi_pinctrl_conf_type type;
+       u32 config_value;
+
+       if (!config)
+               return -EINVAL;
+
+       config_type = pinconf_to_config_param(*config);
+
+       ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
+       if (ret)
+               return ret;
+
+       ret = pinctrl_ops->settings_get_one(pmx->ph, pin, PIN_TYPE, type,
+                                           &config_value);
+       /* Convert SCMI error code to PINCTRL expected error code */
+       if (ret == -EOPNOTSUPP)
+               return -ENOTSUPP;
+       if (ret)
+               return ret;
+
+       *config = pinconf_to_config_packed(config_type, config_value);
+
+       return 0;
+}
+
+static int
+pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs,
+                          u32 **p_config_value,
+                          enum scmi_pinctrl_conf_type **p_config_type)
+{
+       if (num_configs <= SCMI_NUM_CONFIGS)
+               return 0;
+
+       *p_config_value = kcalloc(num_configs, sizeof(**p_config_value), GFP_KERNEL);
+       if (!*p_config_value)
+               return -ENOMEM;
+
+       *p_config_type = kcalloc(num_configs, sizeof(**p_config_type), GFP_KERNEL);
+       if (!*p_config_type) {
+               kfree(*p_config_value);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void
+pinctrl_scmi_free_configs(struct pinctrl_dev *pctldev, u32 num_configs,
+                         u32 **p_config_value,
+                         enum scmi_pinctrl_conf_type **p_config_type)
+{
+       if (num_configs <= SCMI_NUM_CONFIGS)
+               return;
+
+       kfree(*p_config_value);
+       kfree(*p_config_type);
+}
+
+static int pinctrl_scmi_pinconf_set(struct pinctrl_dev *pctldev,
+                                   unsigned int pin,
+                                   unsigned long *configs,
+                                   unsigned int num_configs)
+{
+       int i, ret;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+       enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
+       u32 config_value[SCMI_NUM_CONFIGS];
+       enum scmi_pinctrl_conf_type *p_config_type = config_type;
+       u32 *p_config_value = config_value;
+       enum pin_config_param param;
+
+       if (!configs || !num_configs)
+               return -EINVAL;
+
+       ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
+                                        &p_config_value);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]);
+               if (ret) {
+                       dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+                       goto free_config;
+               }
+               p_config_value[i] = pinconf_to_config_argument(configs[i]);
+       }
+
+       ret = pinctrl_ops->settings_conf(pmx->ph, pin, PIN_TYPE, num_configs,
+                                        p_config_type,  p_config_value);
+       if (ret)
+               dev_err(pmx->dev, "Error parsing config %d\n", ret);
+
+free_config:
+       pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
+                                 &p_config_value);
+       return ret;
+}
+
+static int pinctrl_scmi_pinconf_group_set(struct pinctrl_dev *pctldev,
+                                         unsigned int group,
+                                         unsigned long *configs,
+                                         unsigned int num_configs)
+{
+       int i, ret;
+       struct scmi_pinctrl *pmx =  pinctrl_dev_get_drvdata(pctldev);
+       enum scmi_pinctrl_conf_type config_type[SCMI_NUM_CONFIGS];
+       u32 config_value[SCMI_NUM_CONFIGS];
+       enum scmi_pinctrl_conf_type *p_config_type = config_type;
+       u32 *p_config_value = config_value;
+       enum pin_config_param param;
+
+       if (!configs || !num_configs)
+               return -EINVAL;
+
+       ret = pinctrl_scmi_alloc_configs(pctldev, num_configs, &p_config_type,
+                                        &p_config_value);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < num_configs; i++) {
+               param = pinconf_to_config_param(configs[i]);
+               ret = pinctrl_scmi_map_pinconf_type(param, &p_config_type[i]);
+               if (ret) {
+                       dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+                       goto free_config;
+               }
+
+               p_config_value[i] = pinconf_to_config_argument(configs[i]);
+       }
+
+       ret = pinctrl_ops->settings_conf(pmx->ph, group, GROUP_TYPE,
+                                        num_configs, p_config_type,
+                                        p_config_value);
+       if (ret)
+               dev_err(pmx->dev, "Error parsing config %d", ret);
+
+free_config:
+       pinctrl_scmi_free_configs(pctldev, num_configs, &p_config_type,
+                                 &p_config_value);
+       return ret;
+};
+
+static int pinctrl_scmi_pinconf_group_get(struct pinctrl_dev *pctldev,
+                                         unsigned int group,
+                                         unsigned long *config)
+{
+       int ret;
+       struct scmi_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
+       enum pin_config_param config_type;
+       enum scmi_pinctrl_conf_type type;
+       u32 config_value;
+
+       if (!config)
+               return -EINVAL;
+
+       config_type = pinconf_to_config_param(*config);
+       ret = pinctrl_scmi_map_pinconf_type(config_type, &type);
+       if (ret) {
+               dev_err(pmx->dev, "Error map pinconf_type %d\n", ret);
+               return ret;
+       }
+
+       ret = pinctrl_ops->settings_get_one(pmx->ph, group, GROUP_TYPE, type,
+                                           &config_value);
+       /* Convert SCMI error code to PINCTRL expected error code */
+       if (ret == -EOPNOTSUPP)
+               return -ENOTSUPP;
+       if (ret)
+               return ret;
+
+       *config = pinconf_to_config_packed(config_type, config_value);
+
+       return 0;
+}
+
+static const struct pinconf_ops pinctrl_scmi_pinconf_ops = {
+       .is_generic = true,
+       .pin_config_get = pinctrl_scmi_pinconf_get,
+       .pin_config_set = pinctrl_scmi_pinconf_set,
+       .pin_config_group_set = pinctrl_scmi_pinconf_group_set,
+       .pin_config_group_get = pinctrl_scmi_pinconf_group_get,
+       .pin_config_config_dbg_show = pinconf_generic_dump_config,
+};
+
+static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx,
+                                struct pinctrl_desc *desc)
+{
+       struct pinctrl_pin_desc *pins;
+       unsigned int npins;
+       int ret, i;
+
+       npins = pinctrl_ops->count_get(pmx->ph, PIN_TYPE);
+       /*
+        * npins will never be zero, the scmi pinctrl driver has bailed out
+        * if npins is zero.
+        */
+       pins = devm_kmalloc_array(pmx->dev, npins, sizeof(*pins), GFP_KERNEL);
+       if (!pins)
+               return -ENOMEM;
+
+       for (i = 0; i < npins; i++) {
+               pins[i].number = i;
+               /*
+                * The memory for name is handled by the scmi firmware driver,
+                * no need free here
+                */
+               ret = pinctrl_ops->name_get(pmx->ph, i, PIN_TYPE, &pins[i].name);
+               if (ret)
+                       return dev_err_probe(pmx->dev, ret,
+                                            "Can't get name for pin %d", i);
+       }
+
+       desc->npins = npins;
+       desc->pins = pins;
+       dev_dbg(pmx->dev, "got pins %u", npins);
+
+       return 0;
+}
+
+static int scmi_pinctrl_probe(struct scmi_device *sdev)
+{
+       int ret;
+       struct device *dev = &sdev->dev;
+       struct scmi_pinctrl *pmx;
+       const struct scmi_handle *handle;
+       struct scmi_protocol_handle *ph;
+
+       if (!sdev->handle)
+               return -EINVAL;
+
+       handle = sdev->handle;
+
+       pinctrl_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_PINCTRL, &ph);
+       if (IS_ERR(pinctrl_ops))
+               return PTR_ERR(pinctrl_ops);
+
+       pmx = devm_kzalloc(dev, sizeof(*pmx), GFP_KERNEL);
+       if (!pmx)
+               return -ENOMEM;
+
+       pmx->ph = ph;
+
+       pmx->dev = dev;
+       pmx->pctl_desc.name = DRV_NAME;
+       pmx->pctl_desc.owner = THIS_MODULE;
+       pmx->pctl_desc.pctlops = &pinctrl_scmi_pinctrl_ops;
+       pmx->pctl_desc.pmxops = &pinctrl_scmi_pinmux_ops;
+       pmx->pctl_desc.confops = &pinctrl_scmi_pinconf_ops;
+
+       ret = pinctrl_scmi_get_pins(pmx, &pmx->pctl_desc);
+       if (ret)
+               return ret;
+
+       ret = devm_pinctrl_register_and_init(dev, &pmx->pctl_desc, pmx,
+                                            &pmx->pctldev);
+       if (ret)
+               return dev_err_probe(dev, ret, "Failed to register pinctrl\n");
+
+       pmx->nr_functions = pinctrl_scmi_get_functions_count(pmx->pctldev);
+       pmx->functions = devm_kcalloc(dev, pmx->nr_functions,
+                                     sizeof(*pmx->functions), GFP_KERNEL);
+       if (!pmx->functions)
+               return -ENOMEM;
+
+       return pinctrl_enable(pmx->pctldev);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+       { SCMI_PROTOCOL_PINCTRL, "pinctrl" },
+       { }
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_pinctrl_driver = {
+       .name = DRV_NAME,
+       .probe = scmi_pinctrl_probe,
+       .id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_pinctrl_driver);
+
+MODULE_AUTHOR("Oleksii Moisieiev <oleksii_moisieiev@epam.com>");
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("ARM SCMI pin controller driver");
+MODULE_LICENSE("GPL");
index eb5a8c65426061fec78bced9cf66243debbb561f..20425afc6b331b336c314d5a3f4c6dc9b813382d 100644 (file)
@@ -2045,7 +2045,9 @@ static void rzg2l_gpio_irq_restore(struct rzg2l_pinctrl *pctrl)
 
        for (unsigned int i = 0; i < RZG2L_TINT_MAX_INTERRUPT; i++) {
                struct irq_data *data;
+               unsigned long flags;
                unsigned int virq;
+               int ret;
 
                if (!pctrl->hwirq[i])
                        continue;
@@ -2063,8 +2065,18 @@ static void rzg2l_gpio_irq_restore(struct rzg2l_pinctrl *pctrl)
                        continue;
                }
 
-               if (!irqd_irq_disabled(data))
+               /*
+                * This has to be atomically executed to protect against a concurrent
+                * interrupt.
+                */
+               raw_spin_lock_irqsave(&pctrl->lock.rlock, flags);
+               ret = rzg2l_gpio_irq_set_type(data, irqd_get_trigger_type(data));
+               if (!ret && !irqd_irq_disabled(data))
                        rzg2l_gpio_irq_enable(data);
+               raw_spin_unlock_irqrestore(&pctrl->lock.rlock, flags);
+
+               if (ret)
+                       dev_crit(pctrl->dev, "Failed to set IRQ type for virq=%u\n", virq);
        }
 }
 
index 30951f7131cd98bfdaffb70b2aa30ee3ceb7dbdd..1accdaaf282c5331495e51a6bd71a9203a7c0200 100644 (file)
@@ -721,6 +721,7 @@ static struct miscdevice isst_if_char_driver = {
 static const struct x86_cpu_id hpm_cpu_ids[] = {
        X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D,     NULL),
        X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X,     NULL),
+       X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT,      NULL),
        X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X,    NULL),
        {}
 };
index 1305cba61edd4b957313d7d86fb05158975b3086..aca123783efccdcb73391214d20c3722975222ca 100644 (file)
@@ -588,7 +588,7 @@ static const struct regulator_ops mt6360_chg_otg_ops = {
 };
 
 static const struct regulator_desc mt6360_otg_rdesc = {
-       .of_match = "usb-otg-vbus",
+       .of_match = "usb-otg-vbus-regulator",
        .name = "usb-otg-vbus",
        .ops = &mt6360_chg_otg_ops,
        .owner = THIS_MODULE,
index c345a77f9f78c0a4a03f5a13a7151901b9945a03..e4dbacd50a437df3562b04d485ec38e11a89b216 100644 (file)
@@ -192,6 +192,7 @@ static const int rt9455_voreg_values[] = {
        4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
 };
 
+#if IS_ENABLED(CONFIG_USB_PHY)
 /*
  * When the charger is in boost mode, REG02[7:2] represent boost output
  * voltage.
@@ -207,6 +208,7 @@ static const int rt9455_boost_voltage_values[] = {
        5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
        5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
 };
+#endif
 
 /* REG07[3:0] (VMREG) in uV */
 static const int rt9455_vmreg_values[] = {
index dabac9772741fa64c241ee7f2c6d2d173fc18c7b..2c33653ffdea3e9fe74e7454727bf70c799b09b5 100644 (file)
@@ -1911,19 +1911,24 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
                }
        }
 
-       if (err != -EEXIST)
+       if (err != -EEXIST) {
                regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs);
-       if (IS_ERR(regulator->debugfs))
-               rdev_dbg(rdev, "Failed to create debugfs directory\n");
+               if (IS_ERR(regulator->debugfs)) {
+                       rdev_dbg(rdev, "Failed to create debugfs directory\n");
+                       regulator->debugfs = NULL;
+               }
+       }
 
-       debugfs_create_u32("uA_load", 0444, regulator->debugfs,
-                          &regulator->uA_load);
-       debugfs_create_u32("min_uV", 0444, regulator->debugfs,
-                          &regulator->voltage[PM_SUSPEND_ON].min_uV);
-       debugfs_create_u32("max_uV", 0444, regulator->debugfs,
-                          &regulator->voltage[PM_SUSPEND_ON].max_uV);
-       debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
-                           regulator, &constraint_flags_fops);
+       if (regulator->debugfs) {
+               debugfs_create_u32("uA_load", 0444, regulator->debugfs,
+                                  &regulator->uA_load);
+               debugfs_create_u32("min_uV", 0444, regulator->debugfs,
+                                  &regulator->voltage[PM_SUSPEND_ON].min_uV);
+               debugfs_create_u32("max_uV", 0444, regulator->debugfs,
+                                  &regulator->voltage[PM_SUSPEND_ON].max_uV);
+               debugfs_create_file("constraint_flags", 0444, regulator->debugfs,
+                                   regulator, &constraint_flags_fops);
+       }
 
        /*
         * Check now if the regulator is an always on regulator - if
index fe7ae0f3f46af985a87f4a0b5c33c3fd09f6b1a8..5ab1a0befe12f791389911651d8548fb3611b6f8 100644 (file)
@@ -352,6 +352,9 @@ void *regulator_irq_helper(struct device *dev,
 
        h->irq = irq;
        h->desc = *d;
+       h->desc.name = devm_kstrdup(dev, d->name, GFP_KERNEL);
+       if (!h->desc.name)
+               return ERR_PTR(-ENOMEM);
 
        ret = init_rdev_state(dev, h, rdev, common_errs, per_rdev_errs,
                              rdev_amount);
index ad6587a378d09cc52515475f96512ed5627880be..24cc9fc94e900a43a8bfa8c30c364cedb2b0b948 100644 (file)
@@ -319,15 +319,15 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
        }
 }
 
-#define MT6360_REGULATOR_DESC(_name, _sname, ereg, emask, vreg,        vmask,  \
-                             mreg, mmask, streg, stmask, vranges,      \
-                             vcnts, offon_delay, irq_tbls)             \
+#define MT6360_REGULATOR_DESC(match, _name, _sname, ereg, emask, vreg, \
+                             vmask, mreg, mmask, streg, stmask,        \
+                             vranges, vcnts, offon_delay, irq_tbls)    \
 {                                                                      \
        .desc = {                                                       \
                .name = #_name,                                         \
                .supply_name = #_sname,                                 \
                .id =  MT6360_REGULATOR_##_name,                        \
-               .of_match = of_match_ptr(#_name),                       \
+               .of_match = of_match_ptr(match),                        \
                .regulators_node = of_match_ptr("regulator"),           \
                .of_map_mode = mt6360_regulator_of_map_mode,            \
                .owner = THIS_MODULE,                                   \
@@ -351,21 +351,29 @@ static unsigned int mt6360_regulator_of_map_mode(unsigned int hw_mode)
 }
 
 static const struct mt6360_regulator_desc mt6360_regulator_descs[] =  {
-       MT6360_REGULATOR_DESC(BUCK1, BUCK1_VIN, 0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
+       MT6360_REGULATOR_DESC("buck1", BUCK1, BUCK1_VIN,
+                             0x117, 0x40, 0x110, 0xff, 0x117, 0x30, 0x117, 0x04,
                              buck_vout_ranges, 256, 0, buck1_irq_tbls),
-       MT6360_REGULATOR_DESC(BUCK2, BUCK2_VIN, 0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
+       MT6360_REGULATOR_DESC("buck2", BUCK2, BUCK2_VIN,
+                             0x127, 0x40, 0x120, 0xff, 0x127, 0x30, 0x127, 0x04,
                              buck_vout_ranges, 256, 0, buck2_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO6, LDO_VIN3, 0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
+       MT6360_REGULATOR_DESC("ldo6", LDO6, LDO_VIN3,
+                             0x137, 0x40, 0x13B, 0xff, 0x137, 0x30, 0x137, 0x04,
                              ldo_vout_ranges1, 256, 0, ldo6_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO7, LDO_VIN3, 0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
+       MT6360_REGULATOR_DESC("ldo7", LDO7, LDO_VIN3,
+                             0x131, 0x40, 0x135, 0xff, 0x131, 0x30, 0x131, 0x04,
                              ldo_vout_ranges1, 256, 0, ldo7_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO1, LDO_VIN1, 0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
+       MT6360_REGULATOR_DESC("ldo1", LDO1, LDO_VIN1,
+                             0x217, 0x40, 0x21B, 0xff, 0x217, 0x30, 0x217, 0x04,
                              ldo_vout_ranges2, 256, 0, ldo1_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO2, LDO_VIN1, 0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
+       MT6360_REGULATOR_DESC("ldo2", LDO2, LDO_VIN1,
+                             0x211, 0x40, 0x215, 0xff, 0x211, 0x30, 0x211, 0x04,
                              ldo_vout_ranges2, 256, 0, ldo2_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO3, LDO_VIN1, 0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
+       MT6360_REGULATOR_DESC("ldo3", LDO3, LDO_VIN1,
+                             0x205, 0x40, 0x209, 0xff, 0x205, 0x30, 0x205, 0x04,
                              ldo_vout_ranges2, 256, 100, ldo3_irq_tbls),
-       MT6360_REGULATOR_DESC(LDO5, LDO_VIN2, 0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
+       MT6360_REGULATOR_DESC("ldo5", LDO5, LDO_VIN2,
+                             0x20B, 0x40, 0x20F, 0x7f, 0x20B, 0x30, 0x20B, 0x04,
                              ldo_vout_ranges3, 128, 100, ldo5_irq_tbls),
 };
 
index 656fe330d38f0adbc953b8d42861088a6eaa757b..063e12c08e75f70c002e6f3e859a8bba5e8ef344 100644 (file)
@@ -140,6 +140,7 @@ static const struct of_device_id qcom_refgen_match_table[] = {
        { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
        { }
 };
+MODULE_DEVICE_TABLE(of, qcom_refgen_match_table);
 
 static struct platform_driver qcom_refgen_driver = {
        .probe = qcom_refgen_probe,
index 2d54844c4226bcb273847710808971a70b675281..3079de41ef3f6ebaf82ece371f0f30e90728b38a 100644 (file)
@@ -48,7 +48,7 @@
 
 /* Value */
 #define RTQ2208_RAMP_VALUE_MIN_uV              500
-#define RTQ2208_RAMP_VALUE_MAX_uV              64000
+#define RTQ2208_RAMP_VALUE_MAX_uV              16000
 
 #define RTQ2208_BUCK_MASK(uv_irq, ov_irq)      (1 << ((uv_irq) % 8) | 1 << ((ov_irq) % 8))
 
@@ -142,12 +142,11 @@ static int rtq2208_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
         * Because the relation of seleltion and value is like that
         *
         * seletion: value
-        * 000: 64mv
-        * 001: 32mv
+        * 010: 16mv
         * ...
         * 111: 0.5mv
         *
-        * For example, if I would like to select 64mv, the fls(ramp_delay) - 1 will be 0b111,
+        * For example, if I would like to select 16mv, the fls(ramp_delay) - 1 will be 0b010,
         * and I need to use 0b111 - sel to do the shifting
         */
 
index 086da36abc0b4917a26fc78745dfdb8a48b5cfd5..4955616517ce9caa22f652e9370e7d517098b378 100644 (file)
@@ -84,6 +84,7 @@ static const struct of_device_id regulator_ipq4019_of_match[] = {
        { .compatible = "qcom,vqmmc-ipq4019-regulator", },
        {},
 };
+MODULE_DEVICE_TABLE(of, regulator_ipq4019_of_match);
 
 static struct platform_driver ipq4019_regulator_driver = {
        .probe = ipq4019_regulator_probe,
index 85b27c42cf65ba8c21c105a129391d8322cc00f0..7112f59326095a2d643f5353c89a03051c5e93e5 100644 (file)
@@ -103,9 +103,9 @@ config RESET_INTEL_GW
 
 config RESET_K210
        bool "Reset controller driver for Canaan Kendryte K210 SoC"
-       depends on (SOC_CANAAN || COMPILE_TEST) && OF
+       depends on (SOC_CANAAN_K210 || COMPILE_TEST) && OF
        select MFD_SYSCON
-       default SOC_CANAAN
+       default SOC_CANAAN_K210
        help
          Support for the Canaan Kendryte K210 RISC-V SoC reset controller.
          Say Y if you want to control reset signals provided by this
index b0f6b32016362e6ba810038cd6eea5ce95b4bc35..81d6744e1861fd2c964fe4094985b8d80e876cef 100644 (file)
@@ -32,7 +32,7 @@ obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
 
 obj-$(CONFIG_PCI) += sclp_pci.o
 
-obj-$(subst m,y,$(CONFIG_ZCRYPT)) += sclp_ap.o
+obj-$(subst m,y,$(CONFIG_AP)) += sclp_ap.o
 
 obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
 obj-$(CONFIG_VMCP) += vmcp.o
index 37173cb0f5f5a222b936029b8ff8e7997c401d4d..c57694be9bd32ef8cb9dc8ad794379ef2da44640 100644 (file)
@@ -162,7 +162,8 @@ struct raw3270_request *raw3270_request_alloc(size_t size)
        /*
         * Setup ccw.
         */
-       rq->ccw.cda = virt_to_dma32(rq->buffer);
+       if (rq->buffer)
+               rq->ccw.cda = virt_to_dma32(rq->buffer);
        rq->ccw.flags = CCW_FLAG_SLI;
 
        return rq;
@@ -188,7 +189,8 @@ int raw3270_request_reset(struct raw3270_request *rq)
                return -EBUSY;
        rq->ccw.cmd_code = 0;
        rq->ccw.count = 0;
-       rq->ccw.cda = virt_to_dma32(rq->buffer);
+       if (rq->buffer)
+               rq->ccw.cda = virt_to_dma32(rq->buffer);
        rq->ccw.flags = CCW_FLAG_SLI;
        rq->rescnt = 0;
        rq->rc = 0;
index 675d7ed82356a9494d7df785494bd7d2ce8e2ec6..a07bbecba61cd491826f67fed8f88a9e1b27520e 100644 (file)
@@ -127,10 +127,9 @@ static int s390_vary_chpid(struct chp_id chpid, int on)
 /*
  * Channel measurement related functions
  */
-static ssize_t chp_measurement_chars_read(struct file *filp,
-                                         struct kobject *kobj,
-                                         struct bin_attribute *bin_attr,
-                                         char *buf, loff_t off, size_t count)
+static ssize_t measurement_chars_read(struct file *filp, struct kobject *kobj,
+                                     struct bin_attribute *bin_attr,
+                                     char *buf, loff_t off, size_t count)
 {
        struct channel_path *chp;
        struct device *device;
@@ -143,87 +142,79 @@ static ssize_t chp_measurement_chars_read(struct file *filp,
        return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars,
                                       sizeof(chp->cmg_chars));
 }
+static BIN_ATTR_ADMIN_RO(measurement_chars, sizeof(struct cmg_chars));
 
-static const struct bin_attribute chp_measurement_chars_attr = {
-       .attr = {
-               .name = "measurement_chars",
-               .mode = S_IRUSR,
-       },
-       .size = sizeof(struct cmg_chars),
-       .read = chp_measurement_chars_read,
-};
-
-static void chp_measurement_copy_block(struct cmg_entry *buf,
-                                      struct channel_subsystem *css,
-                                      struct chp_id chpid)
-{
-       void *area;
-       struct cmg_entry *entry, reference_buf;
-       int idx;
-
-       if (chpid.id < 128) {
-               area = css->cub_addr1;
-               idx = chpid.id;
-       } else {
-               area = css->cub_addr2;
-               idx = chpid.id - 128;
-       }
-       entry = area + (idx * sizeof(struct cmg_entry));
-       do {
-               memcpy(buf, entry, sizeof(*entry));
-               memcpy(&reference_buf, entry, sizeof(*entry));
-       } while (reference_buf.values[0] != buf->values[0]);
-}
-
-static ssize_t chp_measurement_read(struct file *filp, struct kobject *kobj,
-                                   struct bin_attribute *bin_attr,
-                                   char *buf, loff_t off, size_t count)
+static ssize_t chp_measurement_copy_block(void *buf, loff_t off, size_t count,
+                                         struct kobject *kobj, bool extended)
 {
        struct channel_path *chp;
        struct channel_subsystem *css;
        struct device *device;
        unsigned int size;
+       void *area, *entry;
+       int id, idx;
 
        device = kobj_to_dev(kobj);
        chp = to_channelpath(device);
        css = to_css(chp->dev.parent);
+       id = chp->chpid.id;
 
-       size = sizeof(struct cmg_entry);
+       if (extended) {
+               /* Check if extended measurement data is available. */
+               if (!chp->extended)
+                       return 0;
+
+               size = sizeof(struct cmg_ext_entry);
+               area = css->ecub[id / CSS_ECUES_PER_PAGE];
+               idx = id % CSS_ECUES_PER_PAGE;
+       } else {
+               size = sizeof(struct cmg_entry);
+               area = css->cub[id / CSS_CUES_PER_PAGE];
+               idx = id % CSS_CUES_PER_PAGE;
+       }
+       entry = area + (idx * size);
 
        /* Only allow single reads. */
        if (off || count < size)
                return 0;
-       chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->chpid);
-       count = size;
-       return count;
+
+       memcpy(buf, entry, size);
+
+       return size;
 }
 
-static const struct bin_attribute chp_measurement_attr = {
-       .attr = {
-               .name = "measurement",
-               .mode = S_IRUSR,
-       },
-       .size = sizeof(struct cmg_entry),
-       .read = chp_measurement_read,
+static ssize_t measurement_read(struct file *filp, struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buf, loff_t off, size_t count)
+{
+       return chp_measurement_copy_block(buf, off, count, kobj, false);
+}
+static BIN_ATTR_ADMIN_RO(measurement, sizeof(struct cmg_entry));
+
+static ssize_t ext_measurement_read(struct file *filp, struct kobject *kobj,
+                                   struct bin_attribute *bin_attr,
+                                   char *buf, loff_t off, size_t count)
+{
+       return chp_measurement_copy_block(buf, off, count, kobj, true);
+}
+static BIN_ATTR_ADMIN_RO(ext_measurement, sizeof(struct cmg_ext_entry));
+
+static struct bin_attribute *measurement_attrs[] = {
+       &bin_attr_measurement_chars,
+       &bin_attr_measurement,
+       &bin_attr_ext_measurement,
+       NULL,
 };
+BIN_ATTRIBUTE_GROUPS(measurement);
 
 void chp_remove_cmg_attr(struct channel_path *chp)
 {
-       device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
-       device_remove_bin_file(&chp->dev, &chp_measurement_attr);
+       device_remove_groups(&chp->dev, measurement_groups);
 }
 
 int chp_add_cmg_attr(struct channel_path *chp)
 {
-       int ret;
-
-       ret = device_create_bin_file(&chp->dev, &chp_measurement_chars_attr);
-       if (ret)
-               return ret;
-       ret = device_create_bin_file(&chp->dev, &chp_measurement_attr);
-       if (ret)
-               device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
-       return ret;
+       return device_add_groups(&chp->dev, measurement_groups);
 }
 
 /*
@@ -401,6 +392,35 @@ static ssize_t chp_esc_show(struct device *dev,
 }
 static DEVICE_ATTR(esc, 0444, chp_esc_show, NULL);
 
+static char apply_max_suffix(unsigned long *value, unsigned long base)
+{
+       static char suffixes[] = { 0, 'K', 'M', 'G', 'T' };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(suffixes) - 1; i++) {
+               if (*value < base || *value % base != 0)
+                       break;
+               *value /= base;
+       }
+
+       return suffixes[i];
+}
+
+static ssize_t speed_bps_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct channel_path *chp = to_channelpath(dev);
+       unsigned long speed = chp->speed;
+       char suffix;
+
+       suffix = apply_max_suffix(&speed, 1000);
+
+       return suffix ? sysfs_emit(buf, "%lu%c\n", speed, suffix) :
+                       sysfs_emit(buf, "%lu\n", speed);
+}
+
+static DEVICE_ATTR_RO(speed_bps);
+
 static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
                                struct bin_attribute *attr, char *buf,
                                loff_t off, size_t count)
@@ -432,6 +452,7 @@ static struct attribute *chp_attrs[] = {
        &dev_attr_chid.attr,
        &dev_attr_chid_external.attr,
        &dev_attr_esc.attr,
+       &dev_attr_speed_bps.attr,
        NULL,
 };
 static struct attribute_group chp_attr_group = {
index 7ee9eba0abcbfaca6915263c06c89e096f54ebdb..a15324a43aa3ad50747297d0ad61299b7aadb2a9 100644 (file)
@@ -51,6 +51,8 @@ struct channel_path {
        /* Channel-measurement related stuff: */
        int cmg;
        int shared;
+       int extended;
+       unsigned long speed;
        struct cmg_chars cmg_chars;
 };
 
index 44ea76f9e1decf7b51338da1363643fd9bdd6475..dcc1e1c34ca2e139367d6eefa7964c87d1432627 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/crw.h>
 #include <asm/isc.h>
 #include <asm/ebcdic.h>
-#include <asm/ap.h>
 
 #include "css.h"
 #include "cio.h"
@@ -40,6 +39,20 @@ static DEFINE_SPINLOCK(chsc_page_lock);
 #define SEI_VF_FLA     0xc0 /* VF flag for Full Link Address */
 #define SEI_RS_CHPID   0x4  /* 4 in RS field indicates CHPID */
 
+static BLOCKING_NOTIFIER_HEAD(chsc_notifiers);
+
+int chsc_notifier_register(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_register(&chsc_notifiers, nb);
+}
+EXPORT_SYMBOL(chsc_notifier_register);
+
+int chsc_notifier_unregister(struct notifier_block *nb)
+{
+       return blocking_notifier_chain_unregister(&chsc_notifiers, nb);
+}
+EXPORT_SYMBOL(chsc_notifier_unregister);
+
 /**
  * chsc_error_from_response() - convert a chsc response to an error
  * @response: chsc response code
@@ -581,7 +594,8 @@ static void chsc_process_sei_ap_cfg_chg(struct chsc_sei_nt0_area *sei_area)
        if (sei_area->rs != 5)
                return;
 
-       ap_bus_cfg_chg();
+       blocking_notifier_call_chain(&chsc_notifiers,
+                                    CHSC_NOTIFY_AP_CFG, NULL);
 }
 
 static void chsc_process_sei_fces_event(struct chsc_sei_nt0_area *sei_area)
@@ -857,22 +871,22 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
        struct {
                struct chsc_header request;
                u32 operation_code : 2;
-               u32 : 30;
+               u32 : 1;
+               u32 e : 1;
+               u32 : 28;
                u32 key : 4;
                u32 : 28;
-               u32 zeroes1;
-               dma32_t cub_addr1;
-               u32 zeroes2;
-               dma32_t cub_addr2;
-               u32 reserved[13];
+               dma64_t cub[CSS_NUM_CUB_PAGES];
+               dma64_t ecub[CSS_NUM_ECUB_PAGES];
+               u32 reserved[5];
                struct chsc_header response;
                u32 status : 8;
                u32 : 4;
                u32 fmt : 4;
                u32 : 16;
-       } *secm_area;
+       } __packed *secm_area;
        unsigned long flags;
-       int ret, ccode;
+       int ret, ccode, i;
 
        spin_lock_irqsave(&chsc_page_lock, flags);
        memset(chsc_page, 0, PAGE_SIZE);
@@ -881,8 +895,12 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
        secm_area->request.code = 0x0016;
 
        secm_area->key = PAGE_DEFAULT_KEY >> 4;
-       secm_area->cub_addr1 = virt_to_dma32(css->cub_addr1);
-       secm_area->cub_addr2 = virt_to_dma32(css->cub_addr2);
+       secm_area->e = 1;
+
+       for (i = 0; i < CSS_NUM_CUB_PAGES; i++)
+               secm_area->cub[i] = (__force dma64_t)virt_to_dma32(css->cub[i]);
+       for (i = 0; i < CSS_NUM_ECUB_PAGES; i++)
+               secm_area->ecub[i] = virt_to_dma64(css->ecub[i]);
 
        secm_area->operation_code = enable ? 0 : 1;
 
@@ -908,19 +926,47 @@ out:
        return ret;
 }
 
+static int cub_alloc(struct channel_subsystem *css)
+{
+       int i;
+
+       for (i = 0; i < CSS_NUM_CUB_PAGES; i++) {
+               css->cub[i] = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
+               if (!css->cub[i])
+                       return -ENOMEM;
+       }
+       for (i = 0; i < CSS_NUM_ECUB_PAGES; i++) {
+               css->ecub[i] = (void *)get_zeroed_page(GFP_KERNEL);
+               if (!css->ecub[i])
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void cub_free(struct channel_subsystem *css)
+{
+       int i;
+
+       for (i = 0; i < CSS_NUM_CUB_PAGES; i++) {
+               free_page((unsigned long)css->cub[i]);
+               css->cub[i] = NULL;
+       }
+       for (i = 0; i < CSS_NUM_ECUB_PAGES; i++) {
+               free_page((unsigned long)css->ecub[i]);
+               css->ecub[i] = NULL;
+       }
+}
+
 int
 chsc_secm(struct channel_subsystem *css, int enable)
 {
        int ret;
 
        if (enable && !css->cm_enabled) {
-               css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
-               css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
-               if (!css->cub_addr1 || !css->cub_addr2) {
-                       free_page((unsigned long)css->cub_addr1);
-                       free_page((unsigned long)css->cub_addr2);
-                       return -ENOMEM;
-               }
+               ret = cub_alloc(css);
+               if (ret)
+                       goto out;
        }
        ret = __chsc_do_secm(css, enable);
        if (!ret) {
@@ -934,10 +980,11 @@ chsc_secm(struct channel_subsystem *css, int enable)
                } else
                        chsc_remove_cmg_attr(css);
        }
-       if (!css->cm_enabled) {
-               free_page((unsigned long)css->cub_addr1);
-               free_page((unsigned long)css->cub_addr2);
-       }
+
+out:
+       if (!css->cm_enabled)
+               cub_free(css);
+
        return ret;
 }
 
@@ -1019,6 +1066,18 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
        }
 }
 
+static unsigned long scmc_get_speed(u32 s, u32 p)
+{
+       unsigned long speed = s;
+
+       if (!p)
+               p = 8;
+       while (p--)
+               speed *= 10;
+
+       return speed;
+}
+
 int chsc_get_channel_measurement_chars(struct channel_path *chp)
 {
        unsigned long flags;
@@ -1035,18 +1094,23 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
                u32 zeroes2;
                u32 not_valid : 1;
                u32 shared : 1;
-               u32 : 22;
+               u32 extended : 1;
+               u32 : 21;
                u32 chpid : 8;
                u32 cmcv : 5;
-               u32 : 11;
+               u32 : 7;
+               u32 cmgp : 4;
                u32 cmgq : 8;
                u32 cmg : 8;
-               u32 zeroes3;
+               u32 : 16;
+               u32 cmgs : 16;
                u32 data[NR_MEASUREMENT_CHARS];
        } *scmc_area;
 
        chp->shared = -1;
        chp->cmg = -1;
+       chp->extended = 0;
+       chp->speed = 0;
 
        if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
                return -EINVAL;
@@ -1076,10 +1140,8 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
 
        chp->cmg = scmc_area->cmg;
        chp->shared = scmc_area->shared;
-       if (chp->cmg != 2 && chp->cmg != 3) {
-               /* No cmg-dependent data. */
-               goto out;
-       }
+       chp->extended = scmc_area->extended;
+       chp->speed = scmc_get_speed(scmc_area->cmgs, scmc_area->cmgp);
        chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
                                  (struct cmg_chars *) &scmc_area->data);
 out:
index 03602295f33503ed20a8dc521053be2e51d33d8d..24cd65dbc5a763979f772177aeba380200ad8aee 100644 (file)
@@ -22,6 +22,11 @@ struct cmg_entry {
        u32 values[NR_MEASUREMENT_ENTRIES];
 };
 
+#define NR_EXT_MEASUREMENT_ENTRIES 16
+struct cmg_ext_entry {
+       u32 values[NR_EXT_MEASUREMENT_ENTRIES];
+};
+
 struct channel_path_desc_fmt1 {
        u8 flags;
        u8 lsn;
index 8613fa937237bde02368523577a485b62b07c5dc..a2e771ebae8ebd55e1cb841f76b44a69ebb2bea7 100644 (file)
@@ -95,7 +95,7 @@ static ssize_t crw_inject_write(struct file *file, const char __user *buf,
                return -EINVAL;
        }
 
-       buffer = vmemdup_user(buf, lbuf);
+       buffer = memdup_user_nul(buf, lbuf);
        if (IS_ERR(buffer))
                return -ENOMEM;
 
index 1d68db1a3d4e473e3628afa519cf4735b8c1398f..781f84901256c529334b8bc332eee7b953952cb3 100644 (file)
@@ -309,7 +309,7 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr,
 {
        struct subchannel *sch = to_subchannel(dev);
 
-       return sprintf(buf, "%01x\n", sch->st);
+       return sysfs_emit(buf, "%01x\n", sch->st);
 }
 
 static DEVICE_ATTR_RO(type);
@@ -319,7 +319,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 {
        struct subchannel *sch = to_subchannel(dev);
 
-       return sprintf(buf, "css:t%01X\n", sch->st);
+       return sysfs_emit(buf, "css:t%01X\n", sch->st);
 }
 
 static DEVICE_ATTR_RO(modalias);
@@ -345,7 +345,7 @@ static ssize_t driver_override_show(struct device *dev,
        ssize_t len;
 
        device_lock(dev);
-       len = snprintf(buf, PAGE_SIZE, "%s\n", sch->driver_override);
+       len = sysfs_emit(buf, "%s\n", sch->driver_override);
        device_unlock(dev);
        return len;
 }
@@ -396,8 +396,8 @@ static ssize_t pimpampom_show(struct device *dev,
        struct subchannel *sch = to_subchannel(dev);
        struct pmcw *pmcw = &sch->schib.pmcw;
 
-       return sprintf(buf, "%02x %02x %02x\n",
-                      pmcw->pim, pmcw->pam, pmcw->pom);
+       return sysfs_emit(buf, "%02x %02x %02x\n",
+                         pmcw->pim, pmcw->pam, pmcw->pom);
 }
 static DEVICE_ATTR_RO(pimpampom);
 
@@ -881,7 +881,7 @@ static ssize_t real_cssid_show(struct device *dev, struct device_attribute *a,
        if (!css->id_valid)
                return -EINVAL;
 
-       return sprintf(buf, "%x\n", css->cssid);
+       return sysfs_emit(buf, "%x\n", css->cssid);
 }
 static DEVICE_ATTR_RO(real_cssid);
 
@@ -904,7 +904,7 @@ static ssize_t cm_enable_show(struct device *dev, struct device_attribute *a,
        int ret;
 
        mutex_lock(&css->mutex);
-       ret = sprintf(buf, "%x\n", css->cm_enabled);
+       ret = sysfs_emit(buf, "%x\n", css->cm_enabled);
        mutex_unlock(&css->mutex);
        return ret;
 }
index ea55505542974044a2613330d4718ab712ddd847..c2b175592bb7360e32a5063030204aa5f203a1dc 100644 (file)
 #define SNID_STATE3_MULTI_PATH    1
 #define SNID_STATE3_SINGLE_PATH           0
 
+/*
+ * Miscellaneous constants
+ */
+
+#define CSS_NUM_CUB_PAGES              2
+#define CSS_CUES_PER_PAGE              128
+#define CSS_NUM_ECUB_PAGES             4
+#define CSS_ECUES_PER_PAGE             64
+
 /*
  * Conditions used to specify which subchannels need evaluation
  */
@@ -122,8 +131,8 @@ struct channel_subsystem {
        struct mutex mutex;
        /* channel measurement related */
        int cm_enabled;
-       void *cub_addr1;
-       void *cub_addr2;
+       void *cub[CSS_NUM_CUB_PAGES];
+       void *ecub[CSS_NUM_ECUB_PAGES];
        /* for orphaned ccw devices */
        struct subchannel *pseudo_subchannel;
 };
index 86993de253451a948aa60e1169a9d2a8d1b6fd74..a4c5c6736b31078b6424a4bc0cb44368b8f12db3 100644 (file)
@@ -50,7 +50,7 @@ DECLARE_EVENT_CLASS(s390_class_schib,
                __entry->devno = schib->pmcw.dev;
                __entry->schib = *schib;
                __entry->pmcw_ena = schib->pmcw.ena;
-               __entry->pmcw_st = schib->pmcw.ena;
+               __entry->pmcw_st = schib->pmcw.st;
                __entry->pmcw_dnv = schib->pmcw.dnv;
                __entry->pmcw_dev = schib->pmcw.dev;
                __entry->pmcw_lpm = schib->pmcw.lpm;
index 0edacd101c124b0ff7b60845ea08e81ee25d0654..bd94811fd9f1f8c01fff5f93f4ed16e84d3a997c 100644 (file)
@@ -4,7 +4,7 @@
 #
 
 ap-objs := ap_bus.o ap_card.o ap_queue.o
-obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o
+obj-$(CONFIG_AP) += 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
index cce0bafd4c926a2bd53693545b505295dd9d425c..c20b4509207980b51ea64de3aee9eb5b7932934a 100644 (file)
 #include <linux/ctype.h>
 #include <linux/module.h>
 #include <asm/uv.h>
+#include <asm/chsc.h>
 
 #include "ap_bus.h"
 #include "ap_debug.h"
 
-/*
- * Module parameters; note though this file itself isn't modular.
- */
+MODULE_AUTHOR("IBM Corporation");
+MODULE_DESCRIPTION("Adjunct Processor Bus driver");
+MODULE_LICENSE("GPL");
+
 int ap_domain_index = -1;      /* Adjunct Processor Domain Index */
 static DEFINE_SPINLOCK(ap_domain_lock);
 module_param_named(domain, ap_domain_index, int, 0440);
@@ -90,8 +92,9 @@ static atomic64_t ap_bindings_complete_count = ATOMIC64_INIT(0);
 /* completion for APQN bindings complete */
 static DECLARE_COMPLETION(ap_apqn_bindings_complete);
 
-static struct ap_config_info *ap_qci_info;
-static struct ap_config_info *ap_qci_info_old;
+static struct ap_config_info qci[2];
+static struct ap_config_info *const ap_qci_info = &qci[0];
+static struct ap_config_info *const ap_qci_info_old = &qci[1];
 
 /*
  * AP bus related debug feature things.
@@ -203,9 +206,7 @@ static int ap_apft_available(void)
  */
 static inline int ap_qact_available(void)
 {
-       if (ap_qci_info)
-               return ap_qci_info->qact;
-       return 0;
+       return ap_qci_info->qact;
 }
 
 /*
@@ -215,9 +216,7 @@ static inline int ap_qact_available(void)
  */
 int ap_sb_available(void)
 {
-       if (ap_qci_info)
-               return ap_qci_info->apsb;
-       return 0;
+       return ap_qci_info->apsb;
 }
 
 /*
@@ -229,23 +228,6 @@ bool ap_is_se_guest(void)
 }
 EXPORT_SYMBOL(ap_is_se_guest);
 
-/*
- * ap_fetch_qci_info(): Fetch cryptographic config info
- *
- * Returns the ap configuration info fetched via PQAP(QCI).
- * On success 0 is returned, on failure a negative errno
- * is returned, e.g. if the PQAP(QCI) instruction is not
- * available, the return value will be -EOPNOTSUPP.
- */
-static inline int ap_fetch_qci_info(struct ap_config_info *info)
-{
-       if (!ap_qci_available())
-               return -EOPNOTSUPP;
-       if (!info)
-               return -EINVAL;
-       return ap_qci(info);
-}
-
 /**
  * ap_init_qci_info(): Allocate and query qci config info.
  * Does also update the static variables ap_max_domain_id
@@ -253,27 +235,12 @@ static inline int ap_fetch_qci_info(struct ap_config_info *info)
  */
 static void __init ap_init_qci_info(void)
 {
-       if (!ap_qci_available()) {
+       if (!ap_qci_available() ||
+           ap_qci(ap_qci_info)) {
                AP_DBF_INFO("%s QCI not supported\n", __func__);
                return;
        }
-
-       ap_qci_info = kzalloc(sizeof(*ap_qci_info), GFP_KERNEL);
-       if (!ap_qci_info)
-               return;
-       ap_qci_info_old = kzalloc(sizeof(*ap_qci_info_old), GFP_KERNEL);
-       if (!ap_qci_info_old) {
-               kfree(ap_qci_info);
-               ap_qci_info = NULL;
-               return;
-       }
-       if (ap_fetch_qci_info(ap_qci_info) != 0) {
-               kfree(ap_qci_info);
-               kfree(ap_qci_info_old);
-               ap_qci_info = NULL;
-               ap_qci_info_old = NULL;
-               return;
-       }
+       memcpy(ap_qci_info_old, ap_qci_info, sizeof(*ap_qci_info));
        AP_DBF_INFO("%s successful fetched initial qci info\n", __func__);
 
        if (ap_qci_info->apxa) {
@@ -288,8 +255,6 @@ static void __init ap_init_qci_info(void)
                                    __func__, ap_max_domain_id);
                }
        }
-
-       memcpy(ap_qci_info_old, ap_qci_info, sizeof(*ap_qci_info));
 }
 
 /*
@@ -312,7 +277,7 @@ static inline int ap_test_config_card_id(unsigned int id)
 {
        if (id > ap_max_adapter_id)
                return 0;
-       if (ap_qci_info)
+       if (ap_qci_info->flags)
                return ap_test_config(ap_qci_info->apm, id);
        return 1;
 }
@@ -329,7 +294,7 @@ int ap_test_config_usage_domain(unsigned int domain)
 {
        if (domain > ap_max_domain_id)
                return 0;
-       if (ap_qci_info)
+       if (ap_qci_info->flags)
                return ap_test_config(ap_qci_info->aqm, domain);
        return 1;
 }
@@ -1061,22 +1026,24 @@ EXPORT_SYMBOL(ap_bus_force_rescan);
 /*
  * A config change has happened, force an ap bus rescan.
  */
-void ap_bus_cfg_chg(void)
+static int ap_bus_cfg_chg(struct notifier_block *nb,
+                         unsigned long action, void *data)
 {
+       if (action != CHSC_NOTIFY_AP_CFG)
+               return NOTIFY_DONE;
+
        pr_debug("%s config change, forcing bus rescan\n", __func__);
 
        ap_bus_force_rescan();
+
+       return NOTIFY_OK;
 }
 
-/*
- * hex2bitmap() - parse hex mask string and set bitmap.
- * Valid strings are "0x012345678" with at least one valid hex number.
- * Rest of the bitmap to the right is padded with 0. No spaces allowed
- * within the string, the leading 0x may be omitted.
- * Returns the bitmask with exactly the bits set as given by the hex
- * string (both in big endian order).
- */
-static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
+static struct notifier_block ap_bus_nb = {
+       .notifier_call = ap_bus_cfg_chg,
+};
+
+int ap_hex2bitmap(const char *str, unsigned long *bitmap, int bits)
 {
        int i, n, b;
 
@@ -1103,6 +1070,7 @@ static int hex2bitmap(const char *str, unsigned long *bitmap, int bits)
                return -EINVAL;
        return 0;
 }
+EXPORT_SYMBOL(ap_hex2bitmap);
 
 /*
  * modify_bitmap() - parse bitmask argument and modify an existing
@@ -1168,7 +1136,7 @@ static int ap_parse_bitmap_str(const char *str, unsigned long *bitmap, int bits,
                rc = modify_bitmap(str, newmap, bits);
        } else {
                memset(newmap, 0, size);
-               rc = hex2bitmap(str, newmap, bits);
+               rc = ap_hex2bitmap(str, newmap, bits);
        }
        return rc;
 }
@@ -1234,7 +1202,7 @@ static BUS_ATTR_RW(ap_domain);
 
 static ssize_t ap_control_domain_mask_show(const struct bus_type *bus, char *buf)
 {
-       if (!ap_qci_info)       /* QCI not supported */
+       if (!ap_qci_info->flags)        /* QCI not supported */
                return sysfs_emit(buf, "not supported\n");
 
        return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
@@ -1248,7 +1216,7 @@ static BUS_ATTR_RO(ap_control_domain_mask);
 
 static ssize_t ap_usage_domain_mask_show(const struct bus_type *bus, char *buf)
 {
-       if (!ap_qci_info)       /* QCI not supported */
+       if (!ap_qci_info->flags)        /* QCI not supported */
                return sysfs_emit(buf, "not supported\n");
 
        return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
@@ -1262,7 +1230,7 @@ static BUS_ATTR_RO(ap_usage_domain_mask);
 
 static ssize_t ap_adapter_mask_show(const struct bus_type *bus, char *buf)
 {
-       if (!ap_qci_info)       /* QCI not supported */
+       if (!ap_qci_info->flags)        /* QCI not supported */
                return sysfs_emit(buf, "not supported\n");
 
        return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n",
@@ -1595,7 +1563,7 @@ static ssize_t features_show(const struct bus_type *bus, char *buf)
 {
        int n = 0;
 
-       if (!ap_qci_info)       /* QCI not supported */
+       if (!ap_qci_info->flags)        /* QCI not supported */
                return sysfs_emit(buf, "-\n");
 
        if (ap_qci_info->apsc)
@@ -2158,11 +2126,11 @@ static inline void ap_scan_adapter(int ap)
  */
 static bool ap_get_configuration(void)
 {
-       if (!ap_qci_info)       /* QCI not supported */
+       if (!ap_qci_info->flags)        /* QCI not supported */
                return false;
 
        memcpy(ap_qci_info_old, ap_qci_info, sizeof(*ap_qci_info));
-       ap_fetch_qci_info(ap_qci_info);
+       ap_qci(ap_qci_info);
 
        return memcmp(ap_qci_info, ap_qci_info_old,
                      sizeof(struct ap_config_info)) != 0;
@@ -2179,7 +2147,7 @@ static bool ap_config_has_new_aps(void)
 
        unsigned long m[BITS_TO_LONGS(AP_DEVICES)];
 
-       if (!ap_qci_info)
+       if (!ap_qci_info->flags)
                return false;
 
        bitmap_andnot(m, (unsigned long *)ap_qci_info->apm,
@@ -2200,7 +2168,7 @@ static bool ap_config_has_new_doms(void)
 {
        unsigned long m[BITS_TO_LONGS(AP_DOMAINS)];
 
-       if (!ap_qci_info)
+       if (!ap_qci_info->flags)
                return false;
 
        bitmap_andnot(m, (unsigned long *)ap_qci_info->aqm,
@@ -2310,7 +2278,82 @@ static void ap_scan_bus_wq_callback(struct work_struct *unused)
        }
 }
 
-static int __init ap_debug_init(void)
+static inline void __exit ap_async_exit(void)
+{
+       if (ap_thread_flag)
+               ap_poll_thread_stop();
+       chsc_notifier_unregister(&ap_bus_nb);
+       cancel_work(&ap_scan_bus_work);
+       hrtimer_cancel(&ap_poll_timer);
+       timer_delete(&ap_scan_bus_timer);
+}
+
+static inline int __init ap_async_init(void)
+{
+       int rc;
+
+       /* Setup the AP bus rescan timer. */
+       timer_setup(&ap_scan_bus_timer, ap_scan_bus_timer_callback, 0);
+
+       /*
+        * Setup the high resolution poll timer.
+        * If we are running under z/VM adjust polling to z/VM polling rate.
+        */
+       if (MACHINE_IS_VM)
+               poll_high_timeout = 1500000;
+       hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+       ap_poll_timer.function = ap_poll_timeout;
+
+       queue_work(system_long_wq, &ap_scan_bus_work);
+
+       rc = chsc_notifier_register(&ap_bus_nb);
+       if (rc)
+               goto out;
+
+       /* Start the low priority AP bus poll thread. */
+       if (!ap_thread_flag)
+               return 0;
+
+       rc = ap_poll_thread_start();
+       if (rc)
+               goto out_notifier;
+
+       return 0;
+
+out_notifier:
+       chsc_notifier_unregister(&ap_bus_nb);
+out:
+       cancel_work(&ap_scan_bus_work);
+       hrtimer_cancel(&ap_poll_timer);
+       timer_delete(&ap_scan_bus_timer);
+       return rc;
+}
+
+static inline void ap_irq_exit(void)
+{
+       if (ap_irq_flag)
+               unregister_adapter_interrupt(&ap_airq);
+}
+
+static inline int __init ap_irq_init(void)
+{
+       int rc;
+
+       if (!ap_interrupts_available() || !ap_useirq)
+               return 0;
+
+       rc = register_adapter_interrupt(&ap_airq);
+       ap_irq_flag = (rc == 0);
+
+       return rc;
+}
+
+static inline void ap_debug_exit(void)
+{
+       debug_unregister(ap_dbf_info);
+}
+
+static inline int __init ap_debug_init(void)
 {
        ap_dbf_info = debug_register("ap", 2, 1,
                                     AP_DBF_MAX_SPRINTF_ARGS * sizeof(long));
@@ -2378,12 +2421,6 @@ static int __init ap_module_init(void)
                ap_domain_index = -1;
        }
 
-       /* enable interrupts if available */
-       if (ap_interrupts_available() && ap_useirq) {
-               rc = register_adapter_interrupt(&ap_airq);
-               ap_irq_flag = (rc == 0);
-       }
-
        /* Create /sys/bus/ap. */
        rc = bus_register(&ap_bus_type);
        if (rc)
@@ -2396,38 +2433,37 @@ static int __init ap_module_init(void)
                goto out_bus;
        ap_root_device->bus = &ap_bus_type;
 
-       /* Setup the AP bus rescan timer. */
-       timer_setup(&ap_scan_bus_timer, ap_scan_bus_timer_callback, 0);
-
-       /*
-        * Setup the high resolution poll timer.
-        * If we are running under z/VM adjust polling to z/VM polling rate.
-        */
-       if (MACHINE_IS_VM)
-               poll_high_timeout = 1500000;
-       hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-       ap_poll_timer.function = ap_poll_timeout;
-
-       /* Start the low priority AP bus poll thread. */
-       if (ap_thread_flag) {
-               rc = ap_poll_thread_start();
-               if (rc)
-                       goto out_work;
-       }
+       /* enable interrupts if available */
+       rc = ap_irq_init();
+       if (rc)
+               goto out_device;
 
-       queue_work(system_long_wq, &ap_scan_bus_work);
+       /* Setup asynchronous work (timers, workqueue, etc). */
+       rc = ap_async_init();
+       if (rc)
+               goto out_irq;
 
        return 0;
 
-out_work:
-       hrtimer_cancel(&ap_poll_timer);
+out_irq:
+       ap_irq_exit();
+out_device:
        root_device_unregister(ap_root_device);
 out_bus:
        bus_unregister(&ap_bus_type);
 out:
-       if (ap_irq_flag)
-               unregister_adapter_interrupt(&ap_airq);
-       kfree(ap_qci_info);
+       ap_debug_exit();
        return rc;
 }
-device_initcall(ap_module_init);
+
+static void __exit ap_module_exit(void)
+{
+       ap_async_exit();
+       ap_irq_exit();
+       root_device_unregister(ap_root_device);
+       bus_unregister(&ap_bus_type);
+       ap_debug_exit();
+}
+
+module_init(ap_module_init);
+module_exit(ap_module_exit);
index 59c7ed49aa02489593ee052b543be348f7df3027..fdbc6fdfdf576f583a09b363989a7feeae950f07 100644 (file)
@@ -343,6 +343,28 @@ int ap_parse_mask_str(const char *str,
                      unsigned long *bitmap, int bits,
                      struct mutex *lock);
 
+/*
+ * ap_hex2bitmap() - Convert a string containing a hexadecimal number (str)
+ * into a bitmap (bitmap) with bits set that correspond to the bits represented
+ * by the hex string. Input and output data is in big endian order.
+ *
+ * str - Input hex string of format "0x1234abcd". The leading "0x" is optional.
+ * At least one digit is required. Must be large enough to hold the number of
+ * bits represented by the bits parameter.
+ *
+ * bitmap - Pointer to a bitmap. Upon successful completion of this function,
+ * this bitmap will have bits set to match the value of str. If bitmap is longer
+ * than str, then the rightmost bits of bitmap are padded with zeros. Must be
+ * large enough to hold the number of bits represented by the bits parameter.
+ *
+ * bits - Length, in bits, of the bitmap represented by str. Must be a multiple
+ * of 8.
+ *
+ * Returns: 0          On success
+ *         -EINVAL     If str format is invalid or bits is not a multiple of 8.
+ */
+int ap_hex2bitmap(const char *str, unsigned long *bitmap, int bits);
+
 /*
  * Interface to wait for the AP bus to have done one initial ap bus
  * scan and all detected APQNs have been bound to device drivers.
index 6e4e8d324a6def068638e3418b8e9beef70a098f..1f647ffd6f4db933f8526f1f6f52c7e3c1e3ade5 100644 (file)
@@ -708,7 +708,7 @@ static ssize_t ap_functions_show(struct device *dev,
 
 static DEVICE_ATTR_RO(ap_functions);
 
-#ifdef CONFIG_ZCRYPT_DEBUG
+#ifdef CONFIG_AP_DEBUG
 static ssize_t states_show(struct device *dev,
                           struct device_attribute *attr, char *buf)
 {
@@ -820,7 +820,7 @@ static struct attribute *ap_queue_dev_attrs[] = {
        &dev_attr_config.attr,
        &dev_attr_chkstop.attr,
        &dev_attr_ap_functions.attr,
-#ifdef CONFIG_ZCRYPT_DEBUG
+#ifdef CONFIG_AP_DEBUG
        &dev_attr_states.attr,
        &dev_attr_last_err_rc.attr,
 #endif
index fc169bc61593955525368f56f5eb1bf3caa414b7..9f76f2d7b66e5854ff42b3ba30aedc1eab5aa864 100644 (file)
@@ -794,10 +794,11 @@ err_put_vdev:
 static void vfio_ap_mdev_link_queue(struct ap_matrix_mdev *matrix_mdev,
                                    struct vfio_ap_queue *q)
 {
-       if (q) {
-               q->matrix_mdev = matrix_mdev;
-               hash_add(matrix_mdev->qtable.queues, &q->mdev_qnode, q->apqn);
-       }
+       if (!q || vfio_ap_mdev_get_queue(matrix_mdev, q->apqn))
+               return;
+
+       q->matrix_mdev = matrix_mdev;
+       hash_add(matrix_mdev->qtable.queues, &q->mdev_qnode, q->apqn);
 }
 
 static void vfio_ap_mdev_link_apqn(struct ap_matrix_mdev *matrix_mdev, int apqn)
@@ -1118,20 +1119,29 @@ static void vfio_ap_mdev_unlink_adapter(struct ap_matrix_mdev *matrix_mdev,
        }
 }
 
-static void vfio_ap_mdev_hot_unplug_adapter(struct ap_matrix_mdev *matrix_mdev,
-                                           unsigned long apid)
+static void vfio_ap_mdev_hot_unplug_adapters(struct ap_matrix_mdev *matrix_mdev,
+                                            unsigned long *apids)
 {
        struct vfio_ap_queue *q, *tmpq;
        struct list_head qlist;
+       unsigned long apid;
+       bool apcb_update = false;
 
        INIT_LIST_HEAD(&qlist);
-       vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, &qlist);
 
-       if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm)) {
-               clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
-               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+       for_each_set_bit_inv(apid, apids, AP_DEVICES) {
+               vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, &qlist);
+
+               if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm)) {
+                       clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
+                       apcb_update = true;
+               }
        }
 
+       /* Only update apcb if needed to avoid impacting guest */
+       if (apcb_update)
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+
        vfio_ap_mdev_reset_qlist(&qlist);
 
        list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) {
@@ -1140,6 +1150,16 @@ static void vfio_ap_mdev_hot_unplug_adapter(struct ap_matrix_mdev *matrix_mdev,
        }
 }
 
+static void vfio_ap_mdev_hot_unplug_adapter(struct ap_matrix_mdev *matrix_mdev,
+                                           unsigned long apid)
+{
+       DECLARE_BITMAP(apids, AP_DEVICES);
+
+       bitmap_zero(apids, AP_DEVICES);
+       set_bit_inv(apid, apids);
+       vfio_ap_mdev_hot_unplug_adapters(matrix_mdev, apids);
+}
+
 /**
  * unassign_adapter_store - parses the APID from @buf and clears the
  * corresponding bit in the mediated matrix device's APM
@@ -1300,20 +1320,29 @@ static void vfio_ap_mdev_unlink_domain(struct ap_matrix_mdev *matrix_mdev,
        }
 }
 
-static void vfio_ap_mdev_hot_unplug_domain(struct ap_matrix_mdev *matrix_mdev,
-                                          unsigned long apqi)
+static void vfio_ap_mdev_hot_unplug_domains(struct ap_matrix_mdev *matrix_mdev,
+                                           unsigned long *apqis)
 {
        struct vfio_ap_queue *q, *tmpq;
        struct list_head qlist;
+       unsigned long apqi;
+       bool apcb_update = false;
 
        INIT_LIST_HEAD(&qlist);
-       vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, &qlist);
 
-       if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
-               clear_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm);
-               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+       for_each_set_bit_inv(apqi, apqis, AP_DOMAINS) {
+               vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, &qlist);
+
+               if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
+                       clear_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm);
+                       apcb_update = true;
+               }
        }
 
+       /* Only update apcb if needed to avoid impacting guest */
+       if (apcb_update)
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+
        vfio_ap_mdev_reset_qlist(&qlist);
 
        list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) {
@@ -1322,6 +1351,16 @@ static void vfio_ap_mdev_hot_unplug_domain(struct ap_matrix_mdev *matrix_mdev,
        }
 }
 
+static void vfio_ap_mdev_hot_unplug_domain(struct ap_matrix_mdev *matrix_mdev,
+                                          unsigned long apqi)
+{
+       DECLARE_BITMAP(apqis, AP_DOMAINS);
+
+       bitmap_zero(apqis, AP_DEVICES);
+       set_bit_inv(apqi, apqis);
+       vfio_ap_mdev_hot_unplug_domains(matrix_mdev, apqis);
+}
+
 /**
  * unassign_domain_store - parses the APQI from @buf and clears the
  * corresponding bit in the mediated matrix device's AQM
@@ -1570,6 +1609,158 @@ static ssize_t guest_matrix_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(guest_matrix);
 
+static ssize_t write_ap_bitmap(unsigned long *bitmap, char *buf, int offset, char sep)
+{
+       return sysfs_emit_at(buf, offset, "0x%016lx%016lx%016lx%016lx%c",
+                        bitmap[0], bitmap[1], bitmap[2], bitmap[3], sep);
+}
+
+static ssize_t ap_config_show(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
+       int idx = 0;
+
+       idx += write_ap_bitmap(matrix_mdev->matrix.apm, buf, idx, ',');
+       idx += write_ap_bitmap(matrix_mdev->matrix.aqm, buf, idx, ',');
+       idx += write_ap_bitmap(matrix_mdev->matrix.adm, buf, idx, '\n');
+
+       return idx;
+}
+
+/* Number of characters needed for a complete hex mask representing the bits in ..  */
+#define AP_DEVICES_STRLEN      (AP_DEVICES / 4 + 3)
+#define AP_DOMAINS_STRLEN      (AP_DOMAINS / 4 + 3)
+#define AP_CONFIG_STRLEN       (AP_DEVICES_STRLEN + 2 * AP_DOMAINS_STRLEN)
+
+static int parse_bitmap(char **strbufptr, unsigned long *bitmap, int nbits)
+{
+       char *curmask;
+
+       curmask = strsep(strbufptr, ",\n");
+       if (!curmask)
+               return -EINVAL;
+
+       bitmap_clear(bitmap, 0, nbits);
+       return ap_hex2bitmap(curmask, bitmap, nbits);
+}
+
+static int ap_matrix_overflow_check(struct ap_matrix_mdev *matrix_mdev)
+{
+       unsigned long bit;
+
+       for_each_set_bit_inv(bit, matrix_mdev->matrix.apm, AP_DEVICES) {
+               if (bit > matrix_mdev->matrix.apm_max)
+                       return -ENODEV;
+       }
+
+       for_each_set_bit_inv(bit, matrix_mdev->matrix.aqm, AP_DOMAINS) {
+               if (bit > matrix_mdev->matrix.aqm_max)
+                       return -ENODEV;
+       }
+
+       for_each_set_bit_inv(bit, matrix_mdev->matrix.adm, AP_DOMAINS) {
+               if (bit > matrix_mdev->matrix.adm_max)
+                       return -ENODEV;
+       }
+
+       return 0;
+}
+
+static void ap_matrix_copy(struct ap_matrix *dst, struct ap_matrix *src)
+{
+       /* This check works around false positive gcc -Wstringop-overread */
+       if (!src)
+               return;
+
+       bitmap_copy(dst->apm, src->apm, AP_DEVICES);
+       bitmap_copy(dst->aqm, src->aqm, AP_DOMAINS);
+       bitmap_copy(dst->adm, src->adm, AP_DOMAINS);
+}
+
+static ssize_t ap_config_store(struct device *dev, struct device_attribute *attr,
+                              const char *buf, size_t count)
+{
+       struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
+       struct ap_matrix m_new, m_old, m_added, m_removed;
+       DECLARE_BITMAP(apm_filtered, AP_DEVICES);
+       unsigned long newbit;
+       char *newbuf, *rest;
+       int rc = count;
+       bool do_update;
+
+       newbuf = kstrndup(buf, AP_CONFIG_STRLEN, GFP_KERNEL);
+       if (!newbuf)
+               return -ENOMEM;
+       rest = newbuf;
+
+       mutex_lock(&ap_perms_mutex);
+       get_update_locks_for_mdev(matrix_mdev);
+
+       /* Save old state */
+       ap_matrix_copy(&m_old, &matrix_mdev->matrix);
+       if (parse_bitmap(&rest, m_new.apm, AP_DEVICES) ||
+           parse_bitmap(&rest, m_new.aqm, AP_DOMAINS) ||
+           parse_bitmap(&rest, m_new.adm, AP_DOMAINS)) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       bitmap_andnot(m_removed.apm, m_old.apm, m_new.apm, AP_DEVICES);
+       bitmap_andnot(m_removed.aqm, m_old.aqm, m_new.aqm, AP_DOMAINS);
+       bitmap_andnot(m_added.apm, m_new.apm, m_old.apm, AP_DEVICES);
+       bitmap_andnot(m_added.aqm, m_new.aqm, m_old.aqm, AP_DOMAINS);
+
+       /* Need new bitmaps in matrix_mdev for validation */
+       ap_matrix_copy(&matrix_mdev->matrix, &m_new);
+
+       /* Ensure new state is valid, else undo new state */
+       rc = vfio_ap_mdev_validate_masks(matrix_mdev);
+       if (rc) {
+               ap_matrix_copy(&matrix_mdev->matrix, &m_old);
+               goto out;
+       }
+       rc = ap_matrix_overflow_check(matrix_mdev);
+       if (rc) {
+               ap_matrix_copy(&matrix_mdev->matrix, &m_old);
+               goto out;
+       }
+       rc = count;
+
+       /* Need old bitmaps in matrix_mdev for unplug/unlink */
+       ap_matrix_copy(&matrix_mdev->matrix, &m_old);
+
+       /* Unlink removed adapters/domains */
+       vfio_ap_mdev_hot_unplug_adapters(matrix_mdev, m_removed.apm);
+       vfio_ap_mdev_hot_unplug_domains(matrix_mdev, m_removed.aqm);
+
+       /* Need new bitmaps in matrix_mdev for linking new adapters/domains */
+       ap_matrix_copy(&matrix_mdev->matrix, &m_new);
+
+       /* Link newly added adapters */
+       for_each_set_bit_inv(newbit, m_added.apm, AP_DEVICES)
+               vfio_ap_mdev_link_adapter(matrix_mdev, newbit);
+
+       for_each_set_bit_inv(newbit, m_added.aqm, AP_DOMAINS)
+               vfio_ap_mdev_link_domain(matrix_mdev, newbit);
+
+       /* filter resources not bound to vfio-ap */
+       do_update = vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered);
+       do_update |= vfio_ap_mdev_filter_cdoms(matrix_mdev);
+
+       /* Apply changes to shadow apbc if things changed */
+       if (do_update) {
+               vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+               reset_queues_for_apids(matrix_mdev, apm_filtered);
+       }
+out:
+       release_update_locks_for_mdev(matrix_mdev);
+       mutex_unlock(&ap_perms_mutex);
+       kfree(newbuf);
+       return rc;
+}
+static DEVICE_ATTR_RW(ap_config);
+
 static struct attribute *vfio_ap_mdev_attrs[] = {
        &dev_attr_assign_adapter.attr,
        &dev_attr_unassign_adapter.attr,
@@ -1577,6 +1768,7 @@ static struct attribute *vfio_ap_mdev_attrs[] = {
        &dev_attr_unassign_domain.attr,
        &dev_attr_assign_control_domain.attr,
        &dev_attr_unassign_control_domain.attr,
+       &dev_attr_ap_config.attr,
        &dev_attr_control_domains.attr,
        &dev_attr_matrix.attr,
        &dev_attr_guest_matrix.attr,
index 98d37aa27044a643825e0632bfe2b445fcd717b1..437a161c865983b353c319079f57f0fcaaf85757 100644 (file)
@@ -75,11 +75,11 @@ extern struct ap_matrix_dev *matrix_dev;
  */
 struct ap_matrix {
        unsigned long apm_max;
-       DECLARE_BITMAP(apm, 256);
+       DECLARE_BITMAP(apm, AP_DEVICES);
        unsigned long aqm_max;
-       DECLARE_BITMAP(aqm, 256);
+       DECLARE_BITMAP(aqm, AP_DOMAINS);
        unsigned long adm_max;
-       DECLARE_BITMAP(adm, 256);
+       DECLARE_BITMAP(adm, AP_DOMAINS);
 };
 
 /**
index 0a3a678ffc7eedb237f3bc72e21ffe4c076c1444..6087547328ce91271eeab7a13c02059299c0c39a 100644 (file)
@@ -658,7 +658,7 @@ int cca_sec2protkey(u16 cardnr, u16 domain,
                               (int)prepcblk->ccp_rtcode,
                               (int)prepcblk->ccp_rscode);
                if (prepcblk->ccp_rtcode == 8 && prepcblk->ccp_rscode == 2290)
-                       rc = -EAGAIN;
+                       rc = -EBUSY;
                else
                        rc = -EIO;
                goto out;
@@ -1263,7 +1263,7 @@ int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
                               (int)prepcblk->ccp_rtcode,
                               (int)prepcblk->ccp_rscode);
                if (prepcblk->ccp_rtcode == 8 && prepcblk->ccp_rscode == 2290)
-                       rc = -EAGAIN;
+                       rc = -EBUSY;
                else
                        rc = -EIO;
                goto out;
@@ -1426,7 +1426,7 @@ int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
                               (int)prepcblk->ccp_rtcode,
                               (int)prepcblk->ccp_rscode);
                if (prepcblk->ccp_rtcode == 8 && prepcblk->ccp_rscode == 2290)
-                       rc = -EAGAIN;
+                       rc = -EBUSY;
                else
                        rc = -EIO;
                goto out;
index eb7f5489ccf95962034a2a135dbc30fa83599973..9bcf8fc69ebe428bff07458406f70be0407d0b39 100644 (file)
@@ -556,13 +556,29 @@ static int check_reply_pl(const u8 *pl, const char *func)
        pl += 2;
        ret = *((u32 *)pl);
        if (ret != 0) {
-               ZCRYPT_DBF_ERR("%s return value 0x%04x != 0\n", func, ret);
+               ZCRYPT_DBF_ERR("%s return value 0x%08x != 0\n", func, ret);
                return -EIO;
        }
 
        return 0;
 }
 
+/* Check ep11 reply cprb, return 0 or suggested errno value. */
+static int check_reply_cprb(const struct ep11_cprb *rep, const char *func)
+{
+       /* check ep11 reply return code field */
+       if (rep->ret_code) {
+               ZCRYPT_DBF_ERR("%s ep11 reply ret_code=0x%08x\n", __func__,
+                              rep->ret_code);
+               if (rep->ret_code == 0x000c0003)
+                       return -EBUSY;
+               else
+                       return -EIO;
+       }
+
+       return 0;
+}
+
 /*
  * Helper function which does an ep11 query with given query type.
  */
@@ -627,6 +643,12 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -877,6 +899,12 @@ static int _ep11_genaeskey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1028,6 +1056,12 @@ static int ep11_cryptsingle(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1185,6 +1219,12 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1339,6 +1379,12 @@ static int _ep11_wrapkey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
index f0b8b709649f29691c3d0976b8a1156da1f6bd81..a3adaec5504e45384eeedf8f82ee160317fcbbf5 100644 (file)
@@ -364,30 +364,33 @@ out:
        return rc;
 }
 
+static void qeth_free_cq(struct qeth_card *card)
+{
+       if (card->qdio.c_q) {
+               qeth_free_qdio_queue(card->qdio.c_q);
+               card->qdio.c_q = NULL;
+       }
+}
+
 static int qeth_alloc_cq(struct qeth_card *card)
 {
        if (card->options.cq == QETH_CQ_ENABLED) {
                QETH_CARD_TEXT(card, 2, "cqon");
-               card->qdio.c_q = qeth_alloc_qdio_queue();
                if (!card->qdio.c_q) {
-                       dev_err(&card->gdev->dev, "Failed to create completion queue\n");
-                       return -ENOMEM;
+                       card->qdio.c_q = qeth_alloc_qdio_queue();
+                       if (!card->qdio.c_q) {
+                               dev_err(&card->gdev->dev,
+                                       "Failed to create completion queue\n");
+                               return -ENOMEM;
+                       }
                }
        } else {
                QETH_CARD_TEXT(card, 2, "nocq");
-               card->qdio.c_q = NULL;
+               qeth_free_cq(card);
        }
        return 0;
 }
 
-static void qeth_free_cq(struct qeth_card *card)
-{
-       if (card->qdio.c_q) {
-               qeth_free_qdio_queue(card->qdio.c_q);
-               card->qdio.c_q = NULL;
-       }
-}
-
 static enum iucv_tx_notify qeth_compute_cq_notification(int sbalf15,
                                                        int delayed)
 {
@@ -2628,6 +2631,10 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
 
        QETH_CARD_TEXT(card, 2, "allcqdbf");
 
+       /* completion */
+       if (qeth_alloc_cq(card))
+               goto out_err;
+
        if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
                QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
                return 0;
@@ -2663,10 +2670,6 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card)
                queue->priority = QETH_QIB_PQUE_PRIO_DEFAULT;
        }
 
-       /* completion */
-       if (qeth_alloc_cq(card))
-               goto out_freeoutq;
-
        return 0;
 
 out_freeoutq:
@@ -2677,6 +2680,8 @@ out_freeoutq:
        qeth_free_buffer_pool(card);
 out_buffer_pool:
        atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
+       qeth_free_cq(card);
+out_err:
        return -ENOMEM;
 }
 
@@ -2684,11 +2689,12 @@ static void qeth_free_qdio_queues(struct qeth_card *card)
 {
        int i, j;
 
+       qeth_free_cq(card);
+
        if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
                QETH_QDIO_UNINITIALIZED)
                return;
 
-       qeth_free_cq(card);
        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) {
                if (card->qdio.in_q->bufs[j].rx_skb) {
                        consume_skb(card->qdio.in_q->bufs[j].rx_skb);
@@ -3742,24 +3748,11 @@ static void qeth_qdio_poll(struct ccw_device *cdev, unsigned long card_ptr)
 
 int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
 {
-       int rc;
-
-       if (card->options.cq ==  QETH_CQ_NOTAVAILABLE) {
-               rc = -1;
-               goto out;
-       } else {
-               if (card->options.cq == cq) {
-                       rc = 0;
-                       goto out;
-               }
-
-               qeth_free_qdio_queues(card);
-               card->options.cq = cq;
-               rc = 0;
-       }
-out:
-       return rc;
+       if (card->options.cq == QETH_CQ_NOTAVAILABLE)
+               return -1;
 
+       card->options.cq = cq;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(qeth_configure_cq);
 
index 58fdf679341dc64ee1768f1d09dc7ce4d549b4bd..65cdc8b77e358546fd1768fe4ec1bb4588c4b692 100644 (file)
@@ -3120,6 +3120,7 @@ static void sd_read_io_hints(struct scsi_disk *sdkp, unsigned char *buffer)
 {
        struct scsi_device *sdp = sdkp->device;
        const struct scsi_io_group_descriptor *desc, *start, *end;
+       u16 permanent_stream_count_old;
        struct scsi_sense_hdr sshdr;
        struct scsi_mode_data data;
        int res;
@@ -3140,12 +3141,13 @@ static void sd_read_io_hints(struct scsi_disk *sdkp, unsigned char *buffer)
        for (desc = start; desc < end; desc++)
                if (!desc->st_enble || !sd_is_perm_stream(sdkp, desc - start))
                        break;
+       permanent_stream_count_old = sdkp->permanent_stream_count;
        sdkp->permanent_stream_count = desc - start;
        if (sdkp->rscs && sdkp->permanent_stream_count < 2)
                sd_printk(KERN_INFO, sdkp,
                          "Unexpected: RSCS has been set and the permanent stream count is %u\n",
                          sdkp->permanent_stream_count);
-       else if (sdkp->permanent_stream_count)
+       else if (sdkp->permanent_stream_count != permanent_stream_count_old)
                sd_printk(KERN_INFO, sdkp, "permanent stream count = %d\n",
                          sdkp->permanent_stream_count);
 }
index efeba8275a6691e20be511e4dcef6ce15e087b61..a09a26bf4988ff200e4f9aa177edd0eb04e9e62f 100644 (file)
@@ -1451,7 +1451,11 @@ static void qcom_slim_ngd_up_worker(struct work_struct *work)
        ctrl = container_of(work, struct qcom_slim_ngd_ctrl, ngd_up_work);
 
        /* Make sure qmi service is up before continuing */
-       wait_for_completion_interruptible(&ctrl->qmi_up);
+       if (!wait_for_completion_interruptible_timeout(&ctrl->qmi_up,
+                                                      msecs_to_jiffies(MSEC_PER_SEC))) {
+               dev_err(ctrl->dev, "QMI wait timeout\n");
+               return;
+       }
 
        mutex_lock(&ctrl->ssr_lock);
        qcom_slim_ngd_enable(ctrl, true);
index ba8f5b5460e1462640087c44a5331619cb14ad1f..fb2bd31387d070387fcf8a579f618dc2b25bdc69 100644 (file)
@@ -7,7 +7,7 @@ obj-y                           += apple/
 obj-y                          += aspeed/
 obj-$(CONFIG_ARCH_AT91)                += atmel/
 obj-y                          += bcm/
-obj-$(CONFIG_SOC_CANAAN)       += canaan/
+obj-$(CONFIG_ARCH_CANAAN)      += canaan/
 obj-$(CONFIG_ARCH_DOVE)                += dove/
 obj-$(CONFIG_MACH_DOVE)                += dove/
 obj-y                          += fsl/
index 43ced2bf844479f70cfdc3a1f1473e2e46ff4351..3121d351fea644ef258234ade5c4b35511eae05f 100644 (file)
@@ -2,9 +2,9 @@
 
 config SOC_K210_SYSCTL
        bool "Canaan Kendryte K210 SoC system controller"
-       depends on RISCV && SOC_CANAAN && OF
+       depends on RISCV && SOC_CANAAN_K210 && OF
        depends on COMMON_CLK_K210
-       default SOC_CANAAN
+       default SOC_CANAAN_K210
        select PM
        select MFD_SYSCON
        help
index 0ab688af308fed625ec8c04723a87911b8da7373..4b0a099b28cc2e88e1ce5d5345eef427f91ee811 100644 (file)
@@ -6,7 +6,7 @@ menu "Hisilicon SoC drivers"
 config KUNPENG_HCCS
        tristate "HCCS driver on Kunpeng SoC"
        depends on ACPI
-       depends on MAILBOX
+       depends on PCC
        depends on ARM64 || COMPILE_TEST
        help
          The Huawei Cache Coherence System (HCCS) is a multi-chip
index 9ff70b38e5e99cab30efad847a6bb5ffe2374dd1..e882a61636ec860622f3bc0aac84e50b2688114c 100644 (file)
@@ -556,6 +556,12 @@ static int hccs_get_all_port_attr(struct hccs_dev *hdev,
                start_id = rsp_head.next_id;
        }
 
+       if (left_buf_len != 0) {
+               dev_err(hdev->dev, "failed to get the expected port number(%u) attribute.\n",
+                       size);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
index b0cd071c4719b780a4ba9026eefc8f50e725a8ea..046522664dc19c1d065c65ab04fd1af19279d9ca 100644 (file)
 
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
+/* dedicate the last GPR_R15 to assign the register address to be poll */
+#define CMDQ_POLL_ADDR_GPR     (15)
 #define CMDQ_EOC_IRQ_EN                BIT(0)
 #define CMDQ_REG_TYPE          1
-#define CMDQ_JUMP_RELATIVE     1
+#define CMDQ_JUMP_RELATIVE     0
+#define CMDQ_JUMP_ABSOLUTE     1
 
 struct cmdq_instruction {
        union {
@@ -55,7 +58,7 @@ int cmdq_dev_get_client_reg(struct device *dev,
                                               "mediatek,gce-client-reg",
                                               3, idx, &spec);
        if (err < 0) {
-               dev_err(dev,
+               dev_warn(dev,
                        "error %d can't parse gce-client-reg property (%d)",
                        err, idx);
 
@@ -105,22 +108,16 @@ void cmdq_mbox_destroy(struct cmdq_client *client)
 }
 EXPORT_SYMBOL(cmdq_mbox_destroy);
 
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
 {
-       struct cmdq_pkt *pkt;
        struct device *dev;
        dma_addr_t dma_addr;
 
-       pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
-       if (!pkt)
-               return ERR_PTR(-ENOMEM);
        pkt->va_base = kzalloc(size, GFP_KERNEL);
-       if (!pkt->va_base) {
-               kfree(pkt);
-               return ERR_PTR(-ENOMEM);
-       }
+       if (!pkt->va_base)
+               return -ENOMEM;
+
        pkt->buf_size = size;
-       pkt->cl = (void *)client;
 
        dev = client->chan->mbox->dev;
        dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
@@ -128,24 +125,20 @@ struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
        if (dma_mapping_error(dev, dma_addr)) {
                dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
                kfree(pkt->va_base);
-               kfree(pkt);
-               return ERR_PTR(-ENOMEM);
+               return -ENOMEM;
        }
 
        pkt->pa_base = dma_addr;
 
-       return pkt;
+       return 0;
 }
 EXPORT_SYMBOL(cmdq_pkt_create);
 
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt)
 {
-       struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
        dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
                         DMA_TO_DEVICE);
        kfree(pkt->va_base);
-       kfree(pkt);
 }
 EXPORT_SYMBOL(cmdq_pkt_destroy);
 
@@ -299,6 +292,32 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_s_mask_value);
 
+int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr)
+{
+       const u16 high_addr_reg_idx  = CMDQ_THR_SPR_IDX0;
+       const u16 value_reg_idx = CMDQ_THR_SPR_IDX1;
+       int ret;
+
+       /* read the value of src_addr into high_addr_reg_idx */
+       ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(src_addr));
+       if (ret < 0)
+               return ret;
+       ret = cmdq_pkt_read_s(pkt, high_addr_reg_idx, CMDQ_ADDR_LOW(src_addr), value_reg_idx);
+       if (ret < 0)
+               return ret;
+
+       /* write the value of value_reg_idx into dst_addr */
+       ret = cmdq_pkt_assign(pkt, high_addr_reg_idx, CMDQ_ADDR_HIGH(dst_addr));
+       if (ret < 0)
+               return ret;
+       ret = cmdq_pkt_write_s(pkt, high_addr_reg_idx, CMDQ_ADDR_LOW(dst_addr), value_reg_idx);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_mem_move);
+
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 {
        struct cmdq_instruction inst = { {0} };
@@ -315,6 +334,21 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear)
 }
 EXPORT_SYMBOL(cmdq_pkt_wfe);
 
+int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event)
+{
+       struct cmdq_instruction inst = {};
+
+       if (event >= CMDQ_MAX_EVENT)
+               return -EINVAL;
+
+       inst.op = CMDQ_CODE_WFE;
+       inst.value = CMDQ_WFE_UPDATE | CMDQ_WFE_UPDATE_VALUE | CMDQ_WFE_WAIT;
+       inst.event = event;
+
+       return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_acquire_event);
+
 int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 {
        struct cmdq_instruction inst = { {0} };
@@ -380,6 +414,53 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 }
 EXPORT_SYMBOL(cmdq_pkt_poll_mask);
 
+int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
+{
+       struct cmdq_instruction inst = { {0} };
+       u8 use_mask = 0;
+       int ret;
+
+       /*
+        * Append an MASK instruction to set the mask for following POLL instruction
+        * which enables use_mask bit.
+        */
+       if (mask != GENMASK(31, 0)) {
+               inst.op = CMDQ_CODE_MASK;
+               inst.mask = ~mask;
+               ret = cmdq_pkt_append_command(pkt, inst);
+               if (ret < 0)
+                       return ret;
+               use_mask = CMDQ_POLL_ENABLE_MASK;
+       }
+
+       /*
+        * POLL is an legacy operation in GCE and it does not support SPR and CMDQ_CODE_LOGIC,
+        * so it can not use cmdq_pkt_assign to keep polling register address to SPR.
+        * If user wants to poll a register address which doesn't have a subsys id,
+        * user needs to use GPR and CMDQ_CODE_MASK to move polling register address to GPR.
+        */
+       inst.op = CMDQ_CODE_MASK;
+       inst.dst_t = CMDQ_REG_TYPE;
+       inst.sop = CMDQ_POLL_ADDR_GPR;
+       inst.value = addr;
+       ret = cmdq_pkt_append_command(pkt, inst);
+       if (ret < 0)
+               return ret;
+
+       /* Append POLL instruction to poll the register address assign to GPR previously. */
+       inst.op = CMDQ_CODE_POLL;
+       inst.dst_t = CMDQ_REG_TYPE;
+       inst.sop = CMDQ_POLL_ADDR_GPR;
+       inst.offset = use_mask;
+       inst.value = value;
+       ret = cmdq_pkt_append_command(pkt, inst);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_poll_addr);
+
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 {
        struct cmdq_instruction inst = {};
@@ -392,17 +473,36 @@ int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
 }
 EXPORT_SYMBOL(cmdq_pkt_assign);
 
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
 {
        struct cmdq_instruction inst = {};
 
        inst.op = CMDQ_CODE_JUMP;
-       inst.offset = CMDQ_JUMP_RELATIVE;
-       inst.value = addr >>
-               cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+       inst.offset = CMDQ_JUMP_ABSOLUTE;
+       inst.value = addr >> shift_pa;
+       return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump_abs);
+
+int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
+{
+       struct cmdq_instruction inst = { {0} };
+
+       inst.op = CMDQ_CODE_JUMP;
+       inst.value = (u32)offset >> shift_pa;
+       return cmdq_pkt_append_command(pkt, inst);
+}
+EXPORT_SYMBOL(cmdq_pkt_jump_rel);
+
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+       struct cmdq_instruction inst = { {0} };
+
+       inst.op = CMDQ_CODE_EOC;
+       inst.value = CMDQ_EOC_IRQ_EN;
        return cmdq_pkt_append_command(pkt, inst);
 }
-EXPORT_SYMBOL(cmdq_pkt_jump);
+EXPORT_SYMBOL(cmdq_pkt_eoc);
 
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
@@ -426,19 +526,4 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_finalize);
 
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
-{
-       int err;
-       struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
-
-       err = mbox_send_message(client->chan, pkt);
-       if (err < 0)
-               return err;
-       /* We can send next packet immediately, so just call txdone. */
-       mbox_client_txdone(client->chan, 0);
-
-       return 0;
-}
-EXPORT_SYMBOL(cmdq_pkt_flush_async);
-
 MODULE_LICENSE("GPL v2");
index 73c256d3950b0c6dbddac14a83d020f51819b1d7..b5af1fb5847ea3fe7572eafff42bbb07d3c0ab1a 100644 (file)
@@ -496,6 +496,39 @@ static const unsigned int mt8188_mutex_mod[DDP_COMPONENT_ID_MAX] = {
        [DDP_COMPONENT_MERGE5] = MT8188_MUTEX_MOD_DISP1_VPP_MERGE4,
 };
 
+static const unsigned int mt8188_mdp_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
+       [MUTEX_MOD_IDX_MDP_RDMA0] = MT8195_MUTEX_MOD_MDP_RDMA0,
+       [MUTEX_MOD_IDX_MDP_RDMA2] = MT8195_MUTEX_MOD_MDP_RDMA2,
+       [MUTEX_MOD_IDX_MDP_RDMA3] = MT8195_MUTEX_MOD_MDP_RDMA3,
+       [MUTEX_MOD_IDX_MDP_FG0] = MT8195_MUTEX_MOD_MDP_FG0,
+       [MUTEX_MOD_IDX_MDP_FG2] = MT8195_MUTEX_MOD_MDP_FG2,
+       [MUTEX_MOD_IDX_MDP_FG3] = MT8195_MUTEX_MOD_MDP_FG3,
+       [MUTEX_MOD_IDX_MDP_HDR0] = MT8195_MUTEX_MOD_MDP_HDR0,
+       [MUTEX_MOD_IDX_MDP_HDR2] = MT8195_MUTEX_MOD_MDP_HDR2,
+       [MUTEX_MOD_IDX_MDP_HDR3] = MT8195_MUTEX_MOD_MDP_HDR3,
+       [MUTEX_MOD_IDX_MDP_AAL0] = MT8195_MUTEX_MOD_MDP_AAL0,
+       [MUTEX_MOD_IDX_MDP_AAL2] = MT8195_MUTEX_MOD_MDP_AAL2,
+       [MUTEX_MOD_IDX_MDP_AAL3] = MT8195_MUTEX_MOD_MDP_AAL3,
+       [MUTEX_MOD_IDX_MDP_RSZ0] = MT8195_MUTEX_MOD_MDP_RSZ0,
+       [MUTEX_MOD_IDX_MDP_RSZ2] = MT8195_MUTEX_MOD_MDP_RSZ2,
+       [MUTEX_MOD_IDX_MDP_RSZ3] = MT8195_MUTEX_MOD_MDP_RSZ3,
+       [MUTEX_MOD_IDX_MDP_MERGE2] = MT8195_MUTEX_MOD_MDP_MERGE2,
+       [MUTEX_MOD_IDX_MDP_MERGE3] = MT8195_MUTEX_MOD_MDP_MERGE3,
+       [MUTEX_MOD_IDX_MDP_TDSHP0] = MT8195_MUTEX_MOD_MDP_TDSHP0,
+       [MUTEX_MOD_IDX_MDP_TDSHP2] = MT8195_MUTEX_MOD_MDP_TDSHP2,
+       [MUTEX_MOD_IDX_MDP_TDSHP3] = MT8195_MUTEX_MOD_MDP_TDSHP3,
+       [MUTEX_MOD_IDX_MDP_COLOR0] = MT8195_MUTEX_MOD_MDP_COLOR0,
+       [MUTEX_MOD_IDX_MDP_COLOR2] = MT8195_MUTEX_MOD_MDP_COLOR2,
+       [MUTEX_MOD_IDX_MDP_COLOR3] = MT8195_MUTEX_MOD_MDP_COLOR3,
+       [MUTEX_MOD_IDX_MDP_OVL0] = MT8195_MUTEX_MOD_MDP_OVL0,
+       [MUTEX_MOD_IDX_MDP_PAD0] = MT8195_MUTEX_MOD_MDP_PAD0,
+       [MUTEX_MOD_IDX_MDP_PAD2] = MT8195_MUTEX_MOD_MDP_PAD2,
+       [MUTEX_MOD_IDX_MDP_PAD3] = MT8195_MUTEX_MOD_MDP_PAD3,
+       [MUTEX_MOD_IDX_MDP_WROT0] = MT8195_MUTEX_MOD_MDP_WROT0,
+       [MUTEX_MOD_IDX_MDP_WROT2] = MT8195_MUTEX_MOD_MDP_WROT2,
+       [MUTEX_MOD_IDX_MDP_WROT3] = MT8195_MUTEX_MOD_MDP_WROT3,
+};
+
 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
        [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
        [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
@@ -735,6 +768,13 @@ static const struct mtk_mutex_data mt8188_mutex_driver_data = {
        .mutex_sof_reg = MT8183_MUTEX0_SOF0,
 };
 
+static const struct mtk_mutex_data mt8188_vpp_mutex_driver_data = {
+       .mutex_sof = mt8188_mutex_sof,
+       .mutex_mod_reg = MT8183_MUTEX0_MOD0,
+       .mutex_sof_reg = MT8183_MUTEX0_SOF0,
+       .mutex_table_mod = mt8188_mdp_mutex_table_mod,
+};
+
 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
        .mutex_mod = mt8192_mutex_mod,
        .mutex_sof = mt8183_mutex_sof,
@@ -1089,6 +1129,7 @@ static const struct of_device_id mutex_driver_dt_match[] = {
        { .compatible = "mediatek,mt8186-disp-mutex", .data = &mt8186_mutex_driver_data },
        { .compatible = "mediatek,mt8186-mdp3-mutex", .data = &mt8186_mdp_mutex_driver_data },
        { .compatible = "mediatek,mt8188-disp-mutex", .data = &mt8188_mutex_driver_data },
+       { .compatible = "mediatek,mt8188-vpp-mutex",  .data = &mt8188_vpp_mutex_driver_data },
        { .compatible = "mediatek,mt8192-disp-mutex", .data = &mt8192_mutex_driver_data },
        { .compatible = "mediatek,mt8195-disp-mutex", .data = &mt8195_mutex_driver_data },
        { .compatible = "mediatek,mt8195-vpp-mutex",  .data = &mt8195_vpp_mutex_driver_data },
index 42572e8c1520d073d971d02ae75eece122587d10..74672a9d6d13dd2518900c50c40ce0c51e68b794 100644 (file)
@@ -48,14 +48,15 @@ static struct socinfo_data socinfo_data_table[] = {
        MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000940),
        MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED),
        MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED),
-       MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010),
-       MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011),
+       MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 838", 0x81880000, 0x00000010),
+       MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 838", 0x81880000, 0x00000011),
        MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080),
        MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0),
        MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED),
        MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED),
        MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED),
        MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED),
+       MTK_SOCINFO_ENTRY("MT8395", "MT8395AV/ZA", "Genio 1200", 0x83950100, CELL_NOT_USED),
 };
 
 static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
@@ -144,7 +145,14 @@ static int mtk_socinfo_get_socinfo_data(struct mtk_socinfo *mtk_socinfop)
                }
        }
 
-       return match_socinfo_index >= 0 ? match_socinfo_index : -ENOENT;
+       if (match_socinfo_index < 0) {
+               dev_warn(mtk_socinfop->dev,
+                        "Unknown MediaTek SoC with ID 0x%08x 0x%08x\n",
+                         cell_data[0], cell_data[1]);
+               return -ENOENT;
+       }
+
+       return match_socinfo_index;
 }
 
 static int mtk_socinfo_probe(struct platform_device *pdev)
index a5fd68411bed587a9796615b65071558bde6fd75..d8457266201758dd3d92e3f68df7b81640d30baa 100644 (file)
@@ -1,6 +1,10 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
 
+#include <linux/bitfield.h>
 #include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -17,6 +21,8 @@
 #define MAX_SLV_ID             8
 #define SLAVE_ID_MASK          0x7
 #define SLAVE_ID_SHIFT         16
+#define SLAVE_ID(addr)         FIELD_GET(GENMASK(19, 16), addr)
+#define VRM_ADDR(addr)         FIELD_GET(GENMASK(19, 4), addr)
 
 /**
  * struct entry_header: header for each entry in cmddb
@@ -147,12 +153,7 @@ static int cmd_db_get_header(const char *id, const struct entry_header **eh,
        if (ret)
                return ret;
 
-       /*
-        * Pad out query string to same length as in DB. NOTE: the output
-        * query string is not necessarily '\0' terminated if it bumps up
-        * against the max size. That's OK and expected.
-        */
-       strncpy(query, id, sizeof(query));
+       strtomem_pad(query, id, 0);
 
        for (i = 0; i < MAX_SLV_ID; i++) {
                rsc_hdr = &cmd_db_header->header[i];
@@ -220,6 +221,30 @@ const void *cmd_db_read_aux_data(const char *id, size_t *len)
 }
 EXPORT_SYMBOL_GPL(cmd_db_read_aux_data);
 
+/**
+ * cmd_db_match_resource_addr() - Compare if both Resource addresses are same
+ *
+ * @addr1: Resource address to compare
+ * @addr2: Resource address to compare
+ *
+ * Return: true if two addresses refer to the same resource, false otherwise
+ */
+bool cmd_db_match_resource_addr(u32 addr1, u32 addr2)
+{
+       /*
+        * Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte
+        * aligned addresses associated with it. Ignore the offset to check
+        * for VRM requests.
+        */
+       if (addr1 == addr2)
+               return true;
+       else if (SLAVE_ID(addr1) == CMD_DB_HW_VRM && VRM_ADDR(addr1) == VRM_ADDR(addr2))
+               return true;
+
+       return false;
+}
+EXPORT_SYMBOL_GPL(cmd_db_match_resource_addr);
+
 /**
  * cmd_db_read_slave_id - Get the slave ID for a given resource address
  *
@@ -362,7 +387,7 @@ static int __init cmd_db_device_init(void)
 {
        return platform_driver_register(&cmd_db_dev_driver);
 }
-arch_initcall(cmd_db_device_init);
+core_initcall(cmd_db_device_init);
 
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Command DB Driver");
 MODULE_LICENSE("GPL v2");
index 656706259353390b1b511ee9b12745a7bb2fd2aa..fb323b3364db4e4c6cea785b7cd9b47472f9a056 100644 (file)
@@ -282,7 +282,7 @@ static const struct regmap_config msm8998_bwmon_regmap_cfg = {
         * Cache is necessary for using regmap fields with non-readable
         * registers.
         */
-       .cache_type             = REGCACHE_RBTREE,
+       .cache_type             = REGCACHE_MAPLE,
 };
 
 static const struct regmap_config msm8998_bwmon_global_regmap_cfg = {
@@ -301,7 +301,7 @@ static const struct regmap_config msm8998_bwmon_global_regmap_cfg = {
         * Cache is necessary for using regmap fields with non-readable
         * registers.
         */
-       .cache_type             = REGCACHE_RBTREE,
+       .cache_type             = REGCACHE_MAPLE,
 };
 
 static const struct reg_field sdm845_cpu_bwmon_reg_fields[] = {
@@ -369,7 +369,7 @@ static const struct regmap_config sdm845_cpu_bwmon_regmap_cfg = {
         * Cache is necessary for using regmap fields with non-readable
         * registers.
         */
-       .cache_type             = REGCACHE_RBTREE,
+       .cache_type             = REGCACHE_MAPLE,
 };
 
 /* BWMON v5 */
@@ -446,7 +446,7 @@ static const struct regmap_config sdm845_llcc_bwmon_regmap_cfg = {
         * Cache is necessary for using regmap fields with non-readable
         * registers.
         */
-       .cache_type             = REGCACHE_RBTREE,
+       .cache_type             = REGCACHE_MAPLE,
 };
 
 static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all)
index f913e9bd57ed4a7aa6d1b99d27a40552713b2536..823fd108fa039ff65b7e577ceab44fbb47d55cce 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/soc/qcom/pdr.h>
 #include <linux/soc/qcom/pmic_glink.h>
+#include <linux/spinlock.h>
 
 enum {
        PMIC_GLINK_CLIENT_BATT = 0,
@@ -36,7 +37,7 @@ struct pmic_glink {
        unsigned int pdr_state;
 
        /* serializing clients list updates */
-       struct mutex client_lock;
+       spinlock_t client_lock;
        struct list_head clients;
 };
 
@@ -58,10 +59,11 @@ static void _devm_pmic_glink_release_client(struct device *dev, void *res)
 {
        struct pmic_glink_client *client = (struct pmic_glink_client *)res;
        struct pmic_glink *pg = client->pg;
+       unsigned long flags;
 
-       mutex_lock(&pg->client_lock);
+       spin_lock_irqsave(&pg->client_lock, flags);
        list_del(&client->node);
-       mutex_unlock(&pg->client_lock);
+       spin_unlock_irqrestore(&pg->client_lock, flags);
 }
 
 struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
@@ -72,6 +74,7 @@ struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
 {
        struct pmic_glink_client *client;
        struct pmic_glink *pg = dev_get_drvdata(dev->parent);
+       unsigned long flags;
 
        client = devres_alloc(_devm_pmic_glink_release_client, sizeof(*client), GFP_KERNEL);
        if (!client)
@@ -83,9 +86,14 @@ struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev,
        client->pdr_notify = pdr;
        client->priv = priv;
 
-       mutex_lock(&pg->client_lock);
+       mutex_lock(&pg->state_lock);
+       spin_lock_irqsave(&pg->client_lock, flags);
+
        list_add(&client->node, &pg->clients);
-       mutex_unlock(&pg->client_lock);
+       client->pdr_notify(client->priv, pg->client_state);
+
+       spin_unlock_irqrestore(&pg->client_lock, flags);
+       mutex_unlock(&pg->state_lock);
 
        devres_add(dev, client);
 
@@ -107,6 +115,7 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
        struct pmic_glink_client *client;
        struct pmic_glink_hdr *hdr;
        struct pmic_glink *pg = dev_get_drvdata(&rpdev->dev);
+       unsigned long flags;
 
        if (len < sizeof(*hdr)) {
                dev_warn(pg->dev, "ignoring truncated message\n");
@@ -115,10 +124,12 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
 
        hdr = data;
 
+       spin_lock_irqsave(&pg->client_lock, flags);
        list_for_each_entry(client, &pg->clients, node) {
                if (client->id == le32_to_cpu(hdr->owner))
                        client->cb(data, len, client->priv);
        }
+       spin_unlock_irqrestore(&pg->client_lock, flags);
 
        return 0;
 }
@@ -158,6 +169,7 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
 {
        struct pmic_glink_client *client;
        unsigned int new_state = pg->client_state;
+       unsigned long flags;
 
        if (pg->client_state != SERVREG_SERVICE_STATE_UP) {
                if (pg->pdr_state == SERVREG_SERVICE_STATE_UP && pg->ept)
@@ -168,8 +180,10 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg)
        }
 
        if (new_state != pg->client_state) {
+               spin_lock_irqsave(&pg->client_lock, flags);
                list_for_each_entry(client, &pg->clients, node)
                        client->pdr_notify(client->priv, new_state);
+               spin_unlock_irqrestore(&pg->client_lock, flags);
                pg->client_state = new_state;
        }
 }
@@ -256,7 +270,7 @@ static int pmic_glink_probe(struct platform_device *pdev)
        pg->dev = &pdev->dev;
 
        INIT_LIST_HEAD(&pg->clients);
-       mutex_init(&pg->client_lock);
+       spin_lock_init(&pg->client_lock);
        mutex_init(&pg->state_lock);
 
        match_data = (unsigned long *)of_device_get_match_data(&pdev->dev);
index 238cd38589dc6ecaf340e990b303ef06a03a0698..39f412bbf2c1e60e8dfeb90b9dff7f90cb0f8553 100644 (file)
@@ -150,6 +150,10 @@ static const struct rpmsg_device_id pmic_pdcharger_ulog_rpmsg_id_match[] = {
        { "PMIC_LOGS_ADSP_APPS" },
        {}
 };
+/*
+ * No MODULE_DEVICE_TABLE intentionally: that's a debugging module, to be
+ * loaded manually only.
+ */
 
 static struct rpmsg_driver pmic_pdcharger_ulog_rpmsg_driver = {
        .probe = pmic_pdcharger_ulog_rpmsg_probe,
index 0216fc24f2caba4df6cd352ae7ca13d107fedeeb..c429d5154aaec2c3115ccefd1c23d712bf6817f7 100644 (file)
@@ -35,11 +35,15 @@ static const struct subsystem_data subsystems[] = {
        { "wpss", 605, 13 },
        { "adsp", 606, 2 },
        { "cdsp", 607, 5 },
+       { "cdsp1", 607, 12 },
+       { "gpdsp0", 607, 17 },
+       { "gpdsp1", 607, 18 },
        { "slpi", 608, 3 },
        { "gpu", 609, 0 },
        { "display", 610, 0 },
        { "adsp_island", 613, 2 },
        { "slpi_island", 613, 3 },
+       { "apss", 631, QCOM_SMEM_HOST_ANY },
 };
 
 struct stats_config {
index 9ca13bcf67d3c047460752b029727b80b307b670..086fe4ba6707fe47d9783225564dac62a14f4465 100644 (file)
@@ -148,6 +148,10 @@ static const struct of_device_id rpm_master_table[] = {
        { .compatible = "qcom,rpm-master-stats" },
        { },
 };
+/*
+ * No MODULE_DEVICE_TABLE intentionally: that's a debugging module, to be
+ * loaded manually only.
+ */
 
 static struct platform_driver master_stats_driver = {
        .probe = master_stats_probe,
index a021dc71807be04571c2a661fda4a58434ba254b..561d8037b50a0734c7ba8ec2602bba9709bc6492 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME
@@ -557,7 +558,7 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs,
                for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) {
                        addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, j);
                        for (k = 0; k < msg->num_cmds; k++) {
-                               if (addr == msg->cmds[k].addr)
+                               if (cmd_db_match_resource_addr(msg->cmds[k].addr, addr))
                                        return -EBUSY;
                        }
                }
@@ -1154,7 +1155,7 @@ static int __init rpmh_driver_init(void)
 {
        return platform_driver_register(&rpmh_driver);
 }
-arch_initcall(rpmh_driver_init);
+core_initcall(rpmh_driver_init);
 
 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver");
 MODULE_LICENSE("GPL v2");
index e8ff9819ac47746b1a93b791d48c9599699327de..277c07a6603d4c5706c939192f7ef7756856b547 100644 (file)
@@ -133,6 +133,7 @@ static const char *const pmic_models[] = {
        [72] = "PMR735D",
        [73] = "PM8550",
        [74] = "PMK8550",
+       [82] = "SMB2360",
 };
 
 struct socinfo_params {
@@ -430,6 +431,7 @@ static const struct soc_id soc_id[] = {
        { qcom_board_id(QRU1000) },
        { qcom_board_id(SM8475_2) },
        { qcom_board_id(QDU1000) },
+       { qcom_board_id(X1E80100) },
        { qcom_board_id(SM8650) },
        { qcom_board_id(SM4450) },
        { qcom_board_id(QDU1010) },
index 5deca747fb7717448107d0b3e7a9102c23760c69..5d94c3f3149448b0cf60de82e81827151344371c 100644 (file)
@@ -24,6 +24,7 @@ config ARCH_RCAR_GEN2
        select RENESAS_IRQC
        select RST_RCAR
        select SYS_SUPPORTS_SH_CMT
+       select SYS_SUPPORTS_SH_TMU
 
 config ARCH_RCAR_GEN3
        bool
@@ -344,6 +345,11 @@ config ARCH_R9A09G011
        help
          This enables support for the Renesas RZ/V2M SoC.
 
+config ARCH_R9A09G057
+       bool "ARM64 Platform support for RZ/V2H(P)"
+       help
+         This enables support for the Renesas RZ/V2H(P) SoC variants.
+
 endif # ARM64
 
 if RISCV
index 8f9b8d3736dcdb47b5f06f03dd8ea4217ae13ed8..172d59e6fbcfae3bcf27135f77a8a32354ea2176 100644 (file)
@@ -75,6 +75,10 @@ static const struct renesas_family fam_rzg3s __initconst __maybe_unused = {
        .name   = "RZ/G3S",
 };
 
+static const struct renesas_family fam_rzv2h __initconst __maybe_unused = {
+       .name   = "RZ/V2H",
+};
+
 static const struct renesas_family fam_rzv2l __initconst __maybe_unused = {
        .name   = "RZ/V2L",
 };
@@ -177,6 +181,11 @@ static const struct renesas_soc soc_rz_g3s __initconst __maybe_unused = {
        .id     = 0x85e0447,
 };
 
+static const struct renesas_soc soc_rz_v2h __initconst __maybe_unused = {
+       .family = &fam_rzv2h,
+       .id     = 0x847a447,
+};
+
 static const struct renesas_soc soc_rz_v2l __initconst __maybe_unused = {
        .family = &fam_rzv2l,
        .id     = 0x8447447,
@@ -407,6 +416,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = {
 #ifdef CONFIG_ARCH_R9A09G011
        { .compatible = "renesas,r9a09g011",    .data = &soc_rz_v2m },
 #endif
+#ifdef CONFIG_ARCH_R9A09G057
+       { .compatible = "renesas,r9a09g057",    .data = &soc_rz_v2h },
+#endif
 #ifdef CONFIG_ARCH_SH73A0
        { .compatible = "renesas,sh73a0",       .data = &soc_shmobile_ag5 },
 #endif
@@ -432,6 +444,11 @@ static const struct renesas_id id_rzg2l __initconst = {
        .mask = 0xfffffff,
 };
 
+static const struct renesas_id id_rzv2h __initconst = {
+       .offset = 0x304,
+       .mask = 0xfffffff,
+};
+
 static const struct renesas_id id_rzv2m __initconst = {
        .offset = 0x104,
        .mask = 0xff,
@@ -449,6 +466,7 @@ static const struct of_device_id renesas_ids[] __initconst = {
        { .compatible = "renesas,r9a07g054-sysc",       .data = &id_rzg2l },
        { .compatible = "renesas,r9a08g045-sysc",       .data = &id_rzg2l },
        { .compatible = "renesas,r9a09g011-sys",        .data = &id_rzv2m },
+       { .compatible = "renesas,r9a09g057-sys",        .data = &id_rzv2h },
        { .compatible = "renesas,prr",                  .data = &id_prr },
        { /* sentinel */ }
 };
@@ -513,7 +531,7 @@ static int __init renesas_soc_init(void)
                        eslo = product & 0xf;
                        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u",
                                                           eshi, eslo);
-               }  else if (id == &id_rzg2l) {
+               }  else if (id == &id_rzg2l || id == &id_rzv2h) {
                        eshi =  ((product >> 28) & 0x0f);
                        soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u",
                                                           eshi);
index d6bfcea5ee653f84dc805fa6c4f4041765ad01ec..91d0ad6ddefc156da64e82a47eb120def1ad6cbd 100644 (file)
@@ -4074,6 +4074,7 @@ static const char * const tegra194_reset_sources[] = {
 };
 
 static const struct tegra_wake_event tegra194_wake_events[] = {
+       TEGRA_WAKE_GPIO("eqos", 20, 0, TEGRA194_MAIN_GPIO(G, 4)),
        TEGRA_WAKE_IRQ("pmu", 24, 209),
        TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)),
        TEGRA_WAKE_IRQ("rtc", 73, 10),
@@ -4210,6 +4211,7 @@ static const char * const tegra234_reset_sources[] = {
 
 static const struct tegra_wake_event tegra234_wake_events[] = {
        TEGRA_WAKE_GPIO("sd-wake", 8, 0, TEGRA234_MAIN_GPIO(G, 7)),
+       TEGRA_WAKE_GPIO("eqos", 20, 0, TEGRA234_MAIN_GPIO(G, 4)),
        TEGRA_WAKE_IRQ("pmu", 24, 209),
        TEGRA_WAKE_GPIO("power", 29, 1, TEGRA234_AON_GPIO(EE, 4)),
        TEGRA_WAKE_GPIO("mgbe", 56, 0, TEGRA234_MAIN_GPIO(Y, 3)),
index 6a1c6b34c414afc1715b07afcc26bcb83a2f806d..88f774db92084892c309930d1cc27103a2e0375b 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <linux/omap-mailbox.h>
 #include <linux/platform_device.h>
 #include <linux/remoteproc.h>
 #include <linux/suspend.h>
@@ -314,7 +313,6 @@ static irqreturn_t wkup_m3_txev_handler(int irq, void *ipc_data)
 static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc)
 {
        struct device *dev = m3_ipc->dev;
-       mbox_msg_t dummy_msg = 0;
        int ret;
 
        if (!m3_ipc->mbox) {
@@ -330,7 +328,7 @@ static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc)
         * the RX callback to avoid multiple interrupts being received
         * by the CM3.
         */
-       ret = mbox_send_message(m3_ipc->mbox, &dummy_msg);
+       ret = mbox_send_message(m3_ipc->mbox, NULL);
        if (ret < 0) {
                dev_err(dev, "%s: mbox_send_message() failed: %d\n",
                        __func__, ret);
@@ -352,7 +350,6 @@ static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc)
 static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc)
 {
        struct device *dev = m3_ipc->dev;
-       mbox_msg_t dummy_msg = 0;
        int ret;
 
        if (!m3_ipc->mbox) {
@@ -361,7 +358,7 @@ static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc)
                return -EIO;
        }
 
-       ret = mbox_send_message(m3_ipc->mbox, &dummy_msg);
+       ret = mbox_send_message(m3_ipc->mbox, NULL);
        if (ret < 0) {
                dev_err(dev, "%s: mbox_send_message() failed: %d\n",
                        __func__, ret);
index 7cc219d78551adbcd99e10e4d59f50653276cac1..e358ac5b4509777e0827630e2f6e58c385f9a54c 100644 (file)
@@ -623,7 +623,7 @@ static int spi_engine_probe(struct platform_device *pdev)
 
        version = readl(spi_engine->base + ADI_AXI_REG_VERSION);
        if (ADI_AXI_PCORE_VER_MAJOR(version) != 1) {
-               dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%c\n",
+               dev_err(&pdev->dev, "Unsupported peripheral version %u.%u.%u\n",
                        ADI_AXI_PCORE_VER_MAJOR(version),
                        ADI_AXI_PCORE_VER_MINOR(version),
                        ADI_AXI_PCORE_VER_PATCH(version));
index 35ef5e8e2ffd253ce16ea0594b2cabcf579cff77..77e9738e42f60ec844c74f09dddf5d90e898d87d 100644 (file)
@@ -151,8 +151,6 @@ static const struct debugfs_reg32 hisi_spi_regs[] = {
        HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),
        HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),
        HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),
-       HISI_SPI_DBGFS_REG("DIN", HISI_SPI_DIN),
-       HISI_SPI_DBGFS_REG("DOUT", HISI_SPI_DOUT),
        HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),
        HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),
        HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),
index 03d125a71fd996071c7de9ccf4c576a31d6f95bd..09f16471c53757f8144e0429f041dd66df5e1be8 100644 (file)
@@ -283,6 +283,7 @@ static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_devi
        }
 
        control = readl_relaxed(qspi->regs + REG_CONTROL);
+       control &= ~CONTROL_CLKRATE_MASK;
        control |= baud_rate_val << CONTROL_CLKRATE_SHIFT;
        writel_relaxed(control, qspi->regs + REG_CONTROL);
        control = readl_relaxed(qspi->regs + REG_CONTROL);
index e4e7ddb7524a99cfd298b19e2939f81cad84722a..4a68abcdcc35351dc1fab0a79b4180387caaa09b 100644 (file)
@@ -1016,10 +1016,8 @@ end_irq:
 static irqreturn_t stm32fx_spi_irq_thread(int irq, void *dev_id)
 {
        struct spi_controller *ctrl = dev_id;
-       struct stm32_spi *spi = spi_controller_get_devdata(ctrl);
 
        spi_finalize_current_transfer(ctrl);
-       stm32fx_spi_disable(spi);
 
        return IRQ_HANDLED;
 }
@@ -1187,6 +1185,8 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
                         ~clrb) | setb,
                        spi->base + spi->cfg->regs->cpol.reg);
 
+       stm32_spi_enable(spi);
+
        spin_unlock_irqrestore(&spi->lock, flags);
 
        return 0;
@@ -1204,7 +1204,6 @@ static void stm32fx_spi_dma_tx_cb(void *data)
 
        if (spi->cur_comm == SPI_SIMPLEX_TX || spi->cur_comm == SPI_3WIRE_TX) {
                spi_finalize_current_transfer(spi->ctrl);
-               stm32fx_spi_disable(spi);
        }
 }
 
@@ -1219,7 +1218,6 @@ static void stm32_spi_dma_rx_cb(void *data)
        struct stm32_spi *spi = data;
 
        spi_finalize_current_transfer(spi->ctrl);
-       spi->cfg->disable(spi);
 }
 
 /**
@@ -1307,8 +1305,6 @@ static int stm32fx_spi_transfer_one_irq(struct stm32_spi *spi)
 
        stm32_spi_set_bits(spi, STM32FX_SPI_CR2, cr2);
 
-       stm32_spi_enable(spi);
-
        /* starting data transfer when buffer is loaded */
        if (spi->tx_buf)
                spi->cfg->write_tx(spi);
@@ -1345,8 +1341,6 @@ static int stm32h7_spi_transfer_one_irq(struct stm32_spi *spi)
 
        spin_lock_irqsave(&spi->lock, flags);
 
-       stm32_spi_enable(spi);
-
        /* Be sure to have data in fifo before starting data transfer */
        if (spi->tx_buf)
                stm32h7_spi_write_txfifo(spi);
@@ -1378,8 +1372,6 @@ static void stm32fx_spi_transfer_one_dma_start(struct stm32_spi *spi)
                 */
                stm32_spi_set_bits(spi, STM32FX_SPI_CR2, STM32FX_SPI_CR2_ERRIE);
        }
-
-       stm32_spi_enable(spi);
 }
 
 /**
@@ -1413,8 +1405,6 @@ static void stm32h7_spi_transfer_one_dma_start(struct stm32_spi *spi)
 
        stm32_spi_set_bits(spi, STM32H7_SPI_IER, ier);
 
-       stm32_spi_enable(spi);
-
        if (STM32_SPI_HOST_MODE(spi))
                stm32_spi_set_bits(spi, STM32H7_SPI_CR1, STM32H7_SPI_CR1_CSTART);
 }
index ff75838c1b5dfa44fccca525c3a8a334051167fb..a2c467d9e92f59c46eea6ec78b3b12a9ae5a6caf 100644 (file)
@@ -4523,6 +4523,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
                wait_for_completion(&done);
                status = message->status;
        }
+       message->complete = NULL;
        message->context = NULL;
 
        return status;
index 73a147202e882f66efe264b383b8f6946e15fe3a..61b507c1878010da267004554397ef5fd67e1d88 100644 (file)
@@ -15,5 +15,6 @@ if TEE
 
 source "drivers/tee/optee/Kconfig"
 source "drivers/tee/amdtee/Kconfig"
+source "drivers/tee/tstee/Kconfig"
 
 endif
index 68da044afbfaeab80fa5187997b5f4f628b7146a..5488cba30bd280e2e4b4421e4c2571d0adbc6321 100644 (file)
@@ -5,3 +5,4 @@ tee-objs += tee_shm.o
 tee-objs += tee_shm_pool.o
 obj-$(CONFIG_OPTEE) += optee/
 obj-$(CONFIG_AMDTEE) += amdtee/
+obj-$(CONFIG_ARM_TSTEE) += tstee/
index 6d0f7062bb870749e3a5117cf6dd98fe9d944a4b..d87050033894b358d40dda767262317200291740 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/kref.h>
 #include <linux/types.h>
 #include "amdtee_if.h"
index e9b63dcb3194cf4cef47b16a698a12f944200ef1..4c21b02be4af75e0483c25d22fadfe37173bbdd4 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <linux/device.h>
 #include <linux/tee.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/psp-tee.h>
 #include <linux/slab.h>
 #include <linux/psp.h>
index 3c15f6a9e91c0a2c24dceecea1815b6bd2600068..e487231d25dc0129bd08e007f169f1ce1c79c3a2 100644 (file)
@@ -9,13 +9,12 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/device.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 #include <linux/firmware.h>
 #include "amdtee_private.h"
-#include "../tee_private.h"
 #include <linux/psp-tee.h>
 
 static struct amdtee_driver_data *drv_data;
index f0303126f199d2a922397a0d80e53d2625ba0088..6346e0bc8a64828d1a66f4c659e2ae3dc18ea3ce 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/psp.h>
 #include "amdtee_private.h"
 
index a91e50be11be6d4e00f2ffe7d0576fcf593fa597..16eb953e14bb686d7f0afbe5f795fd61c1c2b04e 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include "optee_private.h"
 
index 3aed554bc8d8b49c1dcc2619cf113fc2cb71160f..39e688d4e974bc09e35a714800475cea41101bfa 100644 (file)
@@ -9,77 +9,13 @@
 #include <linux/crash_dump.h>
 #include <linux/errno.h>
 #include <linux/io.h>
-#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include "optee_private.h"
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-                              size_t size, size_t align,
-                              int (*shm_register)(struct tee_context *ctx,
-                                                  struct tee_shm *shm,
-                                                  struct page **pages,
-                                                  size_t num_pages,
-                                                  unsigned long start))
-{
-       size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
-       struct page **pages;
-       unsigned int i;
-       int rc = 0;
-
-       /*
-        * Ignore alignment since this is already going to be page aligned
-        * and there's no need for any larger alignment.
-        */
-       shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
-                                      GFP_KERNEL | __GFP_ZERO);
-       if (!shm->kaddr)
-               return -ENOMEM;
-
-       shm->paddr = virt_to_phys(shm->kaddr);
-       shm->size = nr_pages * PAGE_SIZE;
-
-       pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
-       if (!pages) {
-               rc = -ENOMEM;
-               goto err;
-       }
-
-       for (i = 0; i < nr_pages; i++)
-               pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
-
-       shm->pages = pages;
-       shm->num_pages = nr_pages;
-
-       if (shm_register) {
-               rc = shm_register(shm->ctx, shm, pages, nr_pages,
-                                 (unsigned long)shm->kaddr);
-               if (rc)
-                       goto err;
-       }
-
-       return 0;
-err:
-       free_pages_exact(shm->kaddr, shm->size);
-       shm->kaddr = NULL;
-       return rc;
-}
-
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-                              int (*shm_unregister)(struct tee_context *ctx,
-                                                    struct tee_shm *shm))
-{
-       if (shm_unregister)
-               shm_unregister(shm->ctx, shm);
-       free_pages_exact(shm->kaddr, shm->size);
-       shm->kaddr = NULL;
-       kfree(shm->pages);
-       shm->pages = NULL;
-}
-
 static void optee_bus_scan(struct work_struct *work)
 {
        WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
index 1892e49a8e6a68b5c0f8e719042b34b4d2856b42..d296c70ddfdcc8effe7842d33d4ebd8cd8404a3c 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/uuid.h>
 #include "optee_private.h"
 
index ecb5eb079408efd7c75cd5b398f111efaa9e86b4..3235e1c719e84b75c591649453e02f3177ae9e81 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include "optee_private.h"
 #include "optee_ffa.h"
@@ -374,14 +374,14 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx,
 static int pool_ffa_op_alloc(struct tee_shm_pool *pool,
                             struct tee_shm *shm, size_t size, size_t align)
 {
-       return optee_pool_op_alloc_helper(pool, shm, size, align,
-                                         optee_ffa_shm_register);
+       return tee_dyn_shm_alloc_helper(shm, size, align,
+                                       optee_ffa_shm_register);
 }
 
 static void pool_ffa_op_free(struct tee_shm_pool *pool,
                             struct tee_shm *shm)
 {
-       optee_pool_op_free_helper(pool, shm, optee_ffa_shm_unregister);
+       tee_dyn_shm_free_helper(shm, optee_ffa_shm_unregister);
 }
 
 static void pool_ffa_op_destroy_pool(struct tee_shm_pool *pool)
index 05212842b0a50f5498f79a8c7f99d41937ce01ad..0d7878e770cda38b18de5fc3ced492cb9a8cc974 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include "optee_private.h"
 
 struct notif_entry {
index 7a5243c78b55ee1c012b271c538ada48175affff..429cc20be5ccf05afb6dbe061fff729d00ca1c50 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/rhashtable.h>
 #include <linux/semaphore.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include "optee_msg.h"
 
@@ -283,18 +283,6 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 int optee_enumerate_devices(u32 func);
 void optee_unregister_devices(void);
 
-int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-                              size_t size, size_t align,
-                              int (*shm_register)(struct tee_context *ctx,
-                                                  struct tee_shm *shm,
-                                                  struct page **pages,
-                                                  size_t num_pages,
-                                                  unsigned long start));
-void optee_pool_op_free_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
-                              int (*shm_unregister)(struct tee_context *ctx,
-                                                    struct tee_shm *shm));
-
-
 void optee_remove_common(struct optee *optee);
 int optee_open(struct tee_context *ctx, bool cap_memref_null);
 void optee_release(struct tee_context *ctx);
index e69bc6380683af8b0bb9932ca8986d490acf756d..f086812f117931c4f2e63156f21d0e2b2e9d3a02 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include "optee_private.h"
 #include "optee_rpc_cmd.h"
 
index a37f87087e5c896267b6da2f499e0ea27145b31a..844285d4f03c188147918081a64886e29d551687 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 #include "optee_private.h"
@@ -592,19 +592,18 @@ static int pool_op_alloc(struct tee_shm_pool *pool,
         * to be registered with OP-TEE.
         */
        if (shm->flags & TEE_SHM_PRIV)
-               return optee_pool_op_alloc_helper(pool, shm, size, align, NULL);
+               return tee_dyn_shm_alloc_helper(shm, size, align, NULL);
 
-       return optee_pool_op_alloc_helper(pool, shm, size, align,
-                                         optee_shm_register);
+       return tee_dyn_shm_alloc_helper(shm, size, align, optee_shm_register);
 }
 
 static void pool_op_free(struct tee_shm_pool *pool,
                         struct tee_shm *shm)
 {
        if (!(shm->flags & TEE_SHM_PRIV))
-               optee_pool_op_free_helper(pool, shm, optee_shm_unregister);
+               tee_dyn_shm_free_helper(shm, optee_shm_unregister);
        else
-               optee_pool_op_free_helper(pool, shm, NULL);
+               tee_dyn_shm_free_helper(shm, NULL);
 }
 
 static void pool_op_destroy_pool(struct tee_shm_pool *pool)
@@ -1433,7 +1432,7 @@ static optee_invoke_fn *get_invoke_func(struct device *dev)
  * optee_remove is called by platform subsystem to alert the driver
  * that it should release the device
  */
-static int optee_smc_remove(struct platform_device *pdev)
+static void optee_smc_remove(struct platform_device *pdev)
 {
        struct optee *optee = platform_get_drvdata(pdev);
 
@@ -1453,8 +1452,6 @@ static int optee_smc_remove(struct platform_device *pdev)
                memunmap(optee->smc.memremaped_shm);
 
        kfree(optee);
-
-       return 0;
 }
 
 /* optee_shutdown - Device Removal Routine
@@ -1806,7 +1803,7 @@ MODULE_DEVICE_TABLE(of, optee_dt_match);
 
 static struct platform_driver optee_driver = {
        .probe  = optee_probe,
-       .remove = optee_smc_remove,
+       .remove_new = optee_smc_remove,
        .shutdown = optee_shutdown,
        .driver = {
                .name = "optee",
index e59c20d74b36ae08db5d372f46ef03b9c4694cb6..82ad095d2b1c4c2b6c63fe4461271f157105179c 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/idr.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/uaccess.h>
 #include <crypto/hash.h>
 #include <crypto/sha1.h>
index 754e11dcb240898d33e0af4af698ee81c3ff6615..9bc50605227c4cf4f684cc114b9ab7aed92ca728 100644 (file)
 #include <linux/mutex.h>
 #include <linux/types.h>
 
-#define TEE_DEVICE_FLAG_REGISTERED     0x1
-#define TEE_MAX_DEV_NAME_LEN           32
-
-/**
- * struct tee_device - TEE Device representation
- * @name:      name of device
- * @desc:      description of device
- * @id:                unique id of device
- * @flags:     represented by TEE_DEVICE_FLAG_REGISTERED above
- * @dev:       embedded basic device structure
- * @cdev:      embedded cdev
- * @num_users: number of active users of this device
- * @c_no_user: completion used when unregistering the device
- * @mutex:     mutex protecting @num_users and @idr
- * @idr:       register of user space shared memory objects allocated or
- *             registered on this device
- * @pool:      shared memory pool
- */
-struct tee_device {
-       char name[TEE_MAX_DEV_NAME_LEN];
-       const struct tee_desc *desc;
-       int id;
-       unsigned int flags;
-
-       struct device dev;
-       struct cdev cdev;
-
-       size_t num_users;
-       struct completion c_no_users;
-       struct mutex mutex;     /* protects num_users and idr */
-
-       struct idr idr;
-       struct tee_shm_pool *pool;
-};
-
 int tee_shm_get_fd(struct tee_shm *shm);
 
 bool tee_device_get(struct tee_device *teedev);
index 731d9028b67f2b526969a12d8d013d0d34db52e1..daf6e5cfd59ae2a5f98d56113d4c3e23ca175256 100644 (file)
@@ -5,10 +5,11 @@
 #include <linux/anon_inodes.h>
 #include <linux/device.h>
 #include <linux/idr.h>
+#include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include <linux/uaccess.h>
 #include <linux/uio.h>
 #include <linux/highmem.h>
@@ -202,6 +203,70 @@ struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size)
 }
 EXPORT_SYMBOL_GPL(tee_shm_alloc_priv_buf);
 
+int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align,
+                            int (*shm_register)(struct tee_context *ctx,
+                                                struct tee_shm *shm,
+                                                struct page **pages,
+                                                size_t num_pages,
+                                                unsigned long start))
+{
+       size_t nr_pages = roundup(size, PAGE_SIZE) / PAGE_SIZE;
+       struct page **pages;
+       unsigned int i;
+       int rc = 0;
+
+       /*
+        * Ignore alignment since this is already going to be page aligned
+        * and there's no need for any larger alignment.
+        */
+       shm->kaddr = alloc_pages_exact(nr_pages * PAGE_SIZE,
+                                      GFP_KERNEL | __GFP_ZERO);
+       if (!shm->kaddr)
+               return -ENOMEM;
+
+       shm->paddr = virt_to_phys(shm->kaddr);
+       shm->size = nr_pages * PAGE_SIZE;
+
+       pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL);
+       if (!pages) {
+               rc = -ENOMEM;
+               goto err;
+       }
+
+       for (i = 0; i < nr_pages; i++)
+               pages[i] = virt_to_page((u8 *)shm->kaddr + i * PAGE_SIZE);
+
+       shm->pages = pages;
+       shm->num_pages = nr_pages;
+
+       if (shm_register) {
+               rc = shm_register(shm->ctx, shm, pages, nr_pages,
+                                 (unsigned long)shm->kaddr);
+               if (rc)
+                       goto err;
+       }
+
+       return 0;
+err:
+       free_pages_exact(shm->kaddr, shm->size);
+       shm->kaddr = NULL;
+       return rc;
+}
+EXPORT_SYMBOL_GPL(tee_dyn_shm_alloc_helper);
+
+void tee_dyn_shm_free_helper(struct tee_shm *shm,
+                            int (*shm_unregister)(struct tee_context *ctx,
+                                                  struct tee_shm *shm))
+{
+       if (shm_unregister)
+               shm_unregister(shm->ctx, shm);
+       free_pages_exact(shm->kaddr, shm->size);
+       shm->kaddr = NULL;
+       kfree(shm->pages);
+       shm->pages = NULL;
+}
+EXPORT_SYMBOL_GPL(tee_dyn_shm_free_helper);
+
 static struct tee_shm *
 register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags,
                    int id)
index 058bfbac657a9150d16bcd3876c1abcc2b04f846..80004b55628d77444004ac613377d7ceadef22b5 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/dma-buf.h>
 #include <linux/genalloc.h>
 #include <linux/slab.h>
-#include <linux/tee_drv.h>
+#include <linux/tee_core.h>
 #include "tee_private.h"
 
 static int pool_op_gen_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
diff --git a/drivers/tee/tstee/Kconfig b/drivers/tee/tstee/Kconfig
new file mode 100644 (file)
index 0000000..d32f91d
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config ARM_TSTEE
+       tristate "Arm Trusted Services TEE driver"
+       depends on ARM_FFA_TRANSPORT
+       default n
+       help
+         The Trusted Services project provides a framework for developing and
+         deploying device Root of Trust services in FF-A Secure Partitions.
+         This driver provides an interface to make Trusted Services Secure
+         Partitions accessible for user space clients, since the FF-A driver
+         doesn't implement a user space interface directly.
diff --git a/drivers/tee/tstee/Makefile b/drivers/tee/tstee/Makefile
new file mode 100644 (file)
index 0000000..5227020
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+arm-tstee-objs := core.o
+obj-$(CONFIG_ARM_TSTEE) = arm-tstee.o
diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c
new file mode 100644 (file)
index 0000000..533425e
--- /dev/null
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#include <linux/arm_ffa.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/limits.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/tee_core.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+#include <linux/xarray.h>
+#include "tstee_private.h"
+
+#define FFA_DIRECT_REQ_ARG_NUM 5
+#define FFA_INVALID_MEM_HANDLE U64_MAX
+
+static void arg_list_to_ffa_data(const u32 *args,
+                                struct ffa_send_direct_data *data)
+{
+       data->data0 = args[0];
+       data->data1 = args[1];
+       data->data2 = args[2];
+       data->data3 = args[3];
+       data->data4 = args[4];
+}
+
+static void arg_list_from_ffa_data(const struct ffa_send_direct_data *data,
+                                  u32 *args)
+{
+       args[0] = lower_32_bits(data->data0);
+       args[1] = lower_32_bits(data->data1);
+       args[2] = lower_32_bits(data->data2);
+       args[3] = lower_32_bits(data->data3);
+       args[4] = lower_32_bits(data->data4);
+}
+
+static void tstee_get_version(struct tee_device *teedev,
+                             struct tee_ioctl_version_data *vers)
+{
+       struct tstee *tstee = tee_get_drvdata(teedev);
+       struct tee_ioctl_version_data v = {
+               .impl_id = TEE_IMPL_ID_TSTEE,
+               /* FF-A endpoint ID only uses the lower 16 bits */
+               .impl_caps = lower_16_bits(tstee->ffa_dev->vm_id),
+               .gen_caps = 0,
+       };
+
+       *vers = v;
+}
+
+static int tstee_open(struct tee_context *ctx)
+{
+       struct ts_context_data *ctxdata;
+
+       ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
+       if (!ctxdata)
+               return -ENOMEM;
+
+       xa_init_flags(&ctxdata->sess_list, XA_FLAGS_ALLOC);
+
+       ctx->data = ctxdata;
+
+       return 0;
+}
+
+static void tstee_release(struct tee_context *ctx)
+{
+       struct ts_context_data *ctxdata = ctx->data;
+       struct ts_session *sess;
+       unsigned long idx;
+
+       if (!ctxdata)
+               return;
+
+       xa_for_each(&ctxdata->sess_list, idx, sess) {
+               xa_erase(&ctxdata->sess_list, idx);
+               kfree(sess);
+       }
+
+       xa_destroy(&ctxdata->sess_list);
+
+       kfree(ctxdata);
+       ctx->data = NULL;
+}
+
+static int tstee_open_session(struct tee_context *ctx,
+                             struct tee_ioctl_open_session_arg *arg,
+                             struct tee_param *param __always_unused)
+{
+       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+       struct ffa_device *ffa_dev = tstee->ffa_dev;
+       struct ts_context_data *ctxdata = ctx->data;
+       struct ffa_send_direct_data ffa_data;
+       struct ts_session *sess = NULL;
+       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+       u32 sess_id;
+       int rc;
+
+       ffa_args[TS_RPC_CTRL_REG] =
+               TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+                                             TS_RPC_OP_SERVICE_INFO);
+
+       memcpy(ffa_args + TS_RPC_SERVICE_INFO_UUID0, arg->uuid, UUID_SIZE);
+
+       arg_list_to_ffa_data(ffa_args, &ffa_data);
+       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+       if (rc)
+               return rc;
+
+       arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+       if (ffa_args[TS_RPC_SERVICE_INFO_RPC_STATUS] != TS_RPC_OK)
+               return -ENODEV;
+
+       if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX)
+               return -EINVAL;
+
+       sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+       if (!sess)
+               return -ENOMEM;
+
+       sess->iface_id = ffa_args[TS_RPC_SERVICE_INFO_IFACE];
+
+       rc = xa_alloc(&ctxdata->sess_list, &sess_id, sess, xa_limit_32b,
+                     GFP_KERNEL);
+       if (rc) {
+               kfree(sess);
+               return rc;
+       }
+
+       arg->session = sess_id;
+       arg->ret = 0;
+
+       return 0;
+}
+
+static int tstee_close_session(struct tee_context *ctx, u32 session)
+{
+       struct ts_context_data *ctxdata = ctx->data;
+       struct ts_session *sess;
+
+       /* Calls xa_lock() internally */
+       sess = xa_erase(&ctxdata->sess_list, session);
+       if (!sess)
+               return -EINVAL;
+
+       kfree(sess);
+
+       return 0;
+}
+
+static int tstee_invoke_func(struct tee_context *ctx,
+                            struct tee_ioctl_invoke_arg *arg,
+                            struct tee_param *param)
+{
+       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+       struct ffa_device *ffa_dev = tstee->ffa_dev;
+       struct ts_context_data *ctxdata = ctx->data;
+       struct ffa_send_direct_data ffa_data;
+       struct tee_shm *shm = NULL;
+       struct ts_session *sess;
+       u32 req_len, ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+       int shm_id, rc;
+       u8 iface_id;
+       u64 handle;
+       u16 opcode;
+
+       xa_lock(&ctxdata->sess_list);
+       sess = xa_load(&ctxdata->sess_list, arg->session);
+
+       /*
+        * Do this while holding the lock to make sure that the session wasn't
+        * closed meanwhile
+        */
+       if (sess)
+               iface_id = sess->iface_id;
+
+       xa_unlock(&ctxdata->sess_list);
+       if (!sess)
+               return -EINVAL;
+
+       opcode = lower_16_bits(arg->func);
+       shm_id = lower_32_bits(param[0].u.value.a);
+       req_len = lower_32_bits(param[0].u.value.b);
+
+       if (shm_id != 0) {
+               shm = tee_shm_get_from_id(ctx, shm_id);
+               if (IS_ERR(shm))
+                       return PTR_ERR(shm);
+
+               if (shm->size < req_len) {
+                       dev_err(&ffa_dev->dev,
+                               "request doesn't fit into shared memory buffer\n");
+                       rc = -EINVAL;
+                       goto out;
+               }
+
+               handle = shm->sec_world_id;
+       } else {
+               handle = FFA_INVALID_MEM_HANDLE;
+       }
+
+       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id,
+                                                                 opcode);
+       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
+       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
+       ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
+       ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
+
+       arg_list_to_ffa_data(ffa_args, &ffa_data);
+       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+       if (rc)
+               goto out;
+
+       arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+       if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
+               dev_err(&ffa_dev->dev, "invoke_func rpc status: %d\n",
+                       ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
+               rc = -EINVAL;
+               goto out;
+       }
+
+       arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
+       if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
+               param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];
+
+out:
+       if (shm)
+               tee_shm_put(shm);
+
+       return rc;
+}
+
+static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
+                             struct page **pages, size_t num_pages,
+                             unsigned long start __always_unused)
+{
+       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+       struct ffa_device *ffa_dev = tstee->ffa_dev;
+       struct ffa_mem_region_attributes mem_attr = {
+               .receiver = tstee->ffa_dev->vm_id,
+               .attrs = FFA_MEM_RW,
+               .flag = 0,
+       };
+       struct ffa_mem_ops_args mem_args = {
+               .attrs = &mem_attr,
+               .use_txbuf = true,
+               .nattrs = 1,
+               .flags = 0,
+       };
+       struct ffa_send_direct_data ffa_data;
+       struct sg_table sgt;
+       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+       int rc;
+
+       rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
+                                      num_pages * PAGE_SIZE, GFP_KERNEL);
+       if (rc)
+               return rc;
+
+       mem_args.sg = sgt.sgl;
+       rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
+       sg_free_table(&sgt);
+       if (rc)
+               return rc;
+
+       shm->sec_world_id = mem_args.g_handle;
+
+       ffa_args[TS_RPC_CTRL_REG] =
+                       TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+                                                     TS_RPC_OP_RETRIEVE_MEM);
+       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] =
+                       lower_32_bits(shm->sec_world_id);
+       ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] =
+                       upper_32_bits(shm->sec_world_id);
+       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
+       ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;
+
+       arg_list_to_ffa_data(ffa_args, &ffa_data);
+       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+       if (rc) {
+               (void)ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id,
+                                                           0);
+               return rc;
+       }
+
+       arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+       if (ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS] != TS_RPC_OK) {
+               dev_err(&ffa_dev->dev, "shm_register rpc status: %d\n",
+                       ffa_args[TS_RPC_RETRIEVE_MEM_RPC_STATUS]);
+               ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int tstee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm)
+{
+       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
+       struct ffa_device *ffa_dev = tstee->ffa_dev;
+       struct ffa_send_direct_data ffa_data;
+       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+       int rc;
+
+       ffa_args[TS_RPC_CTRL_REG] =
+                       TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+                                                     TS_RPC_OP_RELINQ_MEM);
+       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_LSW] =
+                       lower_32_bits(shm->sec_world_id);
+       ffa_args[TS_RPC_RELINQ_MEM_HANDLE_MSW] =
+                       upper_32_bits(shm->sec_world_id);
+
+       arg_list_to_ffa_data(ffa_args, &ffa_data);
+       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
+       if (rc)
+               return rc;
+       arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+       if (ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS] != TS_RPC_OK) {
+               dev_err(&ffa_dev->dev, "shm_unregister rpc status: %d\n",
+                       ffa_args[TS_RPC_RELINQ_MEM_RPC_STATUS]);
+               return -EINVAL;
+       }
+
+       rc = ffa_dev->ops->mem_ops->memory_reclaim(shm->sec_world_id, 0);
+
+       return rc;
+}
+
+static const struct tee_driver_ops tstee_ops = {
+       .get_version = tstee_get_version,
+       .open = tstee_open,
+       .release = tstee_release,
+       .open_session = tstee_open_session,
+       .close_session = tstee_close_session,
+       .invoke_func = tstee_invoke_func,
+};
+
+static const struct tee_desc tstee_desc = {
+       .name = "tstee-clnt",
+       .ops = &tstee_ops,
+       .owner = THIS_MODULE,
+};
+
+static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
+                        size_t size, size_t align)
+{
+       return tee_dyn_shm_alloc_helper(shm, size, align, tstee_shm_register);
+}
+
+static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm)
+{
+       tee_dyn_shm_free_helper(shm, tstee_shm_unregister);
+}
+
+static void pool_op_destroy_pool(struct tee_shm_pool *pool)
+{
+       kfree(pool);
+}
+
+static const struct tee_shm_pool_ops pool_ops = {
+       .alloc = pool_op_alloc,
+       .free = pool_op_free,
+       .destroy_pool = pool_op_destroy_pool,
+};
+
+static struct tee_shm_pool *tstee_create_shm_pool(void)
+{
+       struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+
+       if (!pool)
+               return ERR_PTR(-ENOMEM);
+
+       pool->ops = &pool_ops;
+
+       return pool;
+}
+
+static bool tstee_check_rpc_compatible(struct ffa_device *ffa_dev)
+{
+       struct ffa_send_direct_data ffa_data;
+       u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
+
+       ffa_args[TS_RPC_CTRL_REG] =
+                       TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
+                                                     TS_RPC_OP_GET_VERSION);
+
+       arg_list_to_ffa_data(ffa_args, &ffa_data);
+       if (ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data))
+               return false;
+
+       arg_list_from_ffa_data(&ffa_data, ffa_args);
+
+       return ffa_args[TS_RPC_GET_VERSION_RESP] == TS_RPC_PROTOCOL_VERSION;
+}
+
+static int tstee_probe(struct ffa_device *ffa_dev)
+{
+       struct tstee *tstee;
+       int rc;
+
+       ffa_dev->ops->msg_ops->mode_32bit_set(ffa_dev);
+
+       if (!tstee_check_rpc_compatible(ffa_dev))
+               return -EINVAL;
+
+       tstee = kzalloc(sizeof(*tstee), GFP_KERNEL);
+       if (!tstee)
+               return -ENOMEM;
+
+       tstee->ffa_dev = ffa_dev;
+
+       tstee->pool = tstee_create_shm_pool();
+       if (IS_ERR(tstee->pool)) {
+               rc = PTR_ERR(tstee->pool);
+               tstee->pool = NULL;
+               goto err_free_tstee;
+       }
+
+       tstee->teedev = tee_device_alloc(&tstee_desc, NULL, tstee->pool, tstee);
+       if (IS_ERR(tstee->teedev)) {
+               rc = PTR_ERR(tstee->teedev);
+               tstee->teedev = NULL;
+               goto err_free_pool;
+       }
+
+       rc = tee_device_register(tstee->teedev);
+       if (rc)
+               goto err_unreg_teedev;
+
+       ffa_dev_set_drvdata(ffa_dev, tstee);
+
+       return 0;
+
+err_unreg_teedev:
+       tee_device_unregister(tstee->teedev);
+err_free_pool:
+       tee_shm_pool_free(tstee->pool);
+err_free_tstee:
+       kfree(tstee);
+       return rc;
+}
+
+static void tstee_remove(struct ffa_device *ffa_dev)
+{
+       struct tstee *tstee = ffa_dev->dev.driver_data;
+
+       tee_device_unregister(tstee->teedev);
+       tee_shm_pool_free(tstee->pool);
+       kfree(tstee);
+}
+
+static const struct ffa_device_id tstee_device_ids[] = {
+       /* TS RPC protocol UUID: bdcd76d7-825e-4751-963b-86d4f84943ac */
+       { TS_RPC_UUID },
+       {}
+};
+
+static struct ffa_driver tstee_driver = {
+       .name = "arm_tstee",
+       .probe = tstee_probe,
+       .remove = tstee_remove,
+       .id_table = tstee_device_ids,
+};
+
+module_ffa_driver(tstee_driver);
+
+MODULE_AUTHOR("Balint Dobszay <balint.dobszay@arm.com>");
+MODULE_DESCRIPTION("Arm Trusted Services TEE driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tee/tstee/tstee_private.h b/drivers/tee/tstee/tstee_private.h
new file mode 100644 (file)
index 0000000..8e58725
--- /dev/null
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, Arm Limited
+ */
+
+#ifndef TSTEE_PRIVATE_H
+#define TSTEE_PRIVATE_H
+
+#include <linux/arm_ffa.h>
+#include <linux/bitops.h>
+#include <linux/tee_core.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+#include <linux/xarray.h>
+
+/*
+ * The description of the ABI implemented in this file is available at
+ * https://trusted-services.readthedocs.io/en/v1.0.0/developer/service-access-protocols.html#abi
+ */
+
+/* UUID of this protocol */
+#define TS_RPC_UUID UUID_INIT(0xbdcd76d7, 0x825e, 0x4751, \
+                             0x96, 0x3b, 0x86, 0xd4, 0xf8, 0x49, 0x43, 0xac)
+
+/* Protocol version*/
+#define TS_RPC_PROTOCOL_VERSION                (1)
+
+/* Status codes */
+#define TS_RPC_OK                      (0)
+
+/* RPC control register */
+#define TS_RPC_CTRL_REG                        (0)
+#define OPCODE_MASK                    GENMASK(15, 0)
+#define IFACE_ID_MASK                  GENMASK(23, 16)
+#define TS_RPC_CTRL_OPCODE(x)          ((u16)(FIELD_GET(OPCODE_MASK, (x))))
+#define TS_RPC_CTRL_IFACE_ID(x)                ((u8)(FIELD_GET(IFACE_ID_MASK, (x))))
+#define TS_RPC_CTRL_PACK_IFACE_OPCODE(i, o)    \
+       (FIELD_PREP(IFACE_ID_MASK, (i)) | FIELD_PREP(OPCODE_MASK, (o)))
+#define TS_RPC_CTRL_SAP_RC             BIT(30)
+#define TS_RPC_CTRL_SAP_ERR            BIT(31)
+
+/* Interface ID for RPC management operations */
+#define TS_RPC_MGMT_IFACE_ID           (0xff)
+
+/* Management calls */
+#define TS_RPC_OP_GET_VERSION          (0x0000)
+#define TS_RPC_GET_VERSION_RESP                (1)
+
+#define TS_RPC_OP_RETRIEVE_MEM         (0x0001)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_LSW (1)
+#define TS_RPC_RETRIEVE_MEM_HANDLE_MSW (2)
+#define TS_RPC_RETRIEVE_MEM_TAG_LSW    (3)
+#define TS_RPC_RETRIEVE_MEM_TAG_MSW    (4)
+#define TS_RPC_RETRIEVE_MEM_RPC_STATUS (1)
+
+#define TS_RPC_OP_RELINQ_MEM           (0x0002)
+#define TS_RPC_RELINQ_MEM_HANDLE_LSW   (1)
+#define TS_RPC_RELINQ_MEM_HANDLE_MSW   (2)
+#define TS_RPC_RELINQ_MEM_RPC_STATUS   (1)
+
+#define TS_RPC_OP_SERVICE_INFO         (0x0003)
+#define TS_RPC_SERVICE_INFO_UUID0      (1)
+#define TS_RPC_SERVICE_INFO_UUID1      (2)
+#define TS_RPC_SERVICE_INFO_UUID2      (3)
+#define TS_RPC_SERVICE_INFO_UUID3      (4)
+#define TS_RPC_SERVICE_INFO_RPC_STATUS (1)
+#define TS_RPC_SERVICE_INFO_IFACE      (2)
+
+/* Service call */
+#define TS_RPC_SERVICE_MEM_HANDLE_LSW  (1)
+#define TS_RPC_SERVICE_MEM_HANDLE_MSW  (2)
+#define TS_RPC_SERVICE_REQ_LEN         (3)
+#define TS_RPC_SERVICE_CLIENT_ID       (4)
+#define TS_RPC_SERVICE_RPC_STATUS      (1)
+#define TS_RPC_SERVICE_STATUS          (2)
+#define TS_RPC_SERVICE_RESP_LEN                (3)
+
+struct tstee {
+       struct ffa_device *ffa_dev;
+       struct tee_device *teedev;
+       struct tee_shm_pool *pool;
+};
+
+struct ts_session {
+       u8 iface_id;
+};
+
+struct ts_context_data {
+       struct xarray sess_list;
+};
+
+#endif /* TSTEE_PRIVATE_H */
index d78d54ae2605e8ab3050dd7a1e68fb13688a78c5..5693cc8b231aacdcf0a90f363a89e15f7bcd93f8 100644 (file)
@@ -139,11 +139,13 @@ struct tz_episode {
  * we keep track of the current position in the history array.
  *
  * @tz_episodes: a list of thermal mitigation episodes
+ * @tz: thermal zone this object belongs to
  * @trips_crossed: an array of trip points crossed by id
  * @nr_trips: the number of trip points currently being crossed
  */
 struct tz_debugfs {
        struct list_head tz_episodes;
+       struct thermal_zone_device *tz;
        int *trips_crossed;
        int nr_trips;
 };
@@ -503,15 +505,23 @@ void thermal_debug_cdev_add(struct thermal_cooling_device *cdev)
  */
 void thermal_debug_cdev_remove(struct thermal_cooling_device *cdev)
 {
-       struct thermal_debugfs *thermal_dbg = cdev->debugfs;
+       struct thermal_debugfs *thermal_dbg;
 
-       if (!thermal_dbg)
+       mutex_lock(&cdev->lock);
+
+       thermal_dbg = cdev->debugfs;
+       if (!thermal_dbg) {
+               mutex_unlock(&cdev->lock);
                return;
+       }
+
+       cdev->debugfs = NULL;
+
+       mutex_unlock(&cdev->lock);
 
        mutex_lock(&thermal_dbg->lock);
 
        thermal_debugfs_cdev_clear(&thermal_dbg->cdev_dbg);
-       cdev->debugfs = NULL;
 
        mutex_unlock(&thermal_dbg->lock);
 
@@ -716,8 +726,7 @@ out:
 
 static void *tze_seq_start(struct seq_file *s, loff_t *pos)
 {
-       struct thermal_zone_device *tz = s->private;
-       struct thermal_debugfs *thermal_dbg = tz->debugfs;
+       struct thermal_debugfs *thermal_dbg = s->private;
        struct tz_debugfs *tz_dbg = &thermal_dbg->tz_dbg;
 
        mutex_lock(&thermal_dbg->lock);
@@ -727,8 +736,7 @@ static void *tze_seq_start(struct seq_file *s, loff_t *pos)
 
 static void *tze_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-       struct thermal_zone_device *tz = s->private;
-       struct thermal_debugfs *thermal_dbg = tz->debugfs;
+       struct thermal_debugfs *thermal_dbg = s->private;
        struct tz_debugfs *tz_dbg = &thermal_dbg->tz_dbg;
 
        return seq_list_next(v, &tz_dbg->tz_episodes, pos);
@@ -736,15 +744,15 @@ static void *tze_seq_next(struct seq_file *s, void *v, loff_t *pos)
 
 static void tze_seq_stop(struct seq_file *s, void *v)
 {
-       struct thermal_zone_device *tz = s->private;
-       struct thermal_debugfs *thermal_dbg = tz->debugfs;
+       struct thermal_debugfs *thermal_dbg = s->private;
 
        mutex_unlock(&thermal_dbg->lock);
 }
 
 static int tze_seq_show(struct seq_file *s, void *v)
 {
-       struct thermal_zone_device *tz = s->private;
+       struct thermal_debugfs *thermal_dbg = s->private;
+       struct thermal_zone_device *tz = thermal_dbg->tz_dbg.tz;
        struct thermal_trip *trip;
        struct tz_episode *tze;
        const char *type;
@@ -810,6 +818,8 @@ void thermal_debug_tz_add(struct thermal_zone_device *tz)
 
        tz_dbg = &thermal_dbg->tz_dbg;
 
+       tz_dbg->tz = tz;
+
        tz_dbg->trips_crossed = kzalloc(sizeof(int) * tz->num_trips, GFP_KERNEL);
        if (!tz_dbg->trips_crossed) {
                thermal_debugfs_remove_id(thermal_dbg);
@@ -818,23 +828,44 @@ void thermal_debug_tz_add(struct thermal_zone_device *tz)
 
        INIT_LIST_HEAD(&tz_dbg->tz_episodes);
 
-       debugfs_create_file("mitigations", 0400, thermal_dbg->d_top, tz, &tze_fops);
+       debugfs_create_file("mitigations", 0400, thermal_dbg->d_top,
+                           thermal_dbg, &tze_fops);
 
        tz->debugfs = thermal_dbg;
 }
 
 void thermal_debug_tz_remove(struct thermal_zone_device *tz)
 {
-       struct thermal_debugfs *thermal_dbg = tz->debugfs;
+       struct thermal_debugfs *thermal_dbg;
+       struct tz_episode *tze, *tmp;
+       struct tz_debugfs *tz_dbg;
+       int *trips_crossed;
 
-       if (!thermal_dbg)
+       mutex_lock(&tz->lock);
+
+       thermal_dbg = tz->debugfs;
+       if (!thermal_dbg) {
+               mutex_unlock(&tz->lock);
                return;
+       }
+
+       tz->debugfs = NULL;
+
+       mutex_unlock(&tz->lock);
+
+       tz_dbg = &thermal_dbg->tz_dbg;
 
        mutex_lock(&thermal_dbg->lock);
 
-       tz->debugfs = NULL;
+       trips_crossed = tz_dbg->trips_crossed;
+
+       list_for_each_entry_safe(tze, tmp, &tz_dbg->tz_episodes, node) {
+               list_del(&tze->node);
+               kfree(tze);
+       }
 
        mutex_unlock(&thermal_dbg->lock);
 
        thermal_debugfs_remove_id(thermal_dbg);
+       kfree(trips_crossed);
 }
index 1aa3e55c8b47da2cdb93ef2e846a88d239a35369..6a7b286f6f5aba2fb268ac7275bc1a6fd2ef61dd 100644 (file)
@@ -293,9 +293,6 @@ static inline int serial8250_in_MCR(struct uart_8250_port *up)
        return mctrl;
 }
 
-bool alpha_jensen(void);
-void alpha_jensen_set_mctrl(struct uart_port *port, unsigned int mctrl);
-
 #ifdef CONFIG_SERIAL_8250_PNP
 int serial8250_pnp_init(void);
 void serial8250_pnp_exit(void);
diff --git a/drivers/tty/serial/8250/8250_alpha.c b/drivers/tty/serial/8250/8250_alpha.c
deleted file mode 100644 (file)
index 58e7032..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-
-#include <asm/machvec.h>
-#include "8250.h"
-
-bool alpha_jensen(void)
-{
-       return !strcmp(alpha_mv.vector_name, "Jensen");
-}
-
-void alpha_jensen_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-       /*
-        * Digital did something really horribly wrong with the OUT1 and OUT2
-        * lines on Alpha Jensen.  The failure mode is that if either is
-        * cleared, the machine locks up with endless interrupts.
-        */
-       mctrl |= TIOCM_OUT1 | TIOCM_OUT2;
-
-       serial8250_do_set_mctrl(port, mctrl);
-}
index b62ad9006780ce4b7266ffb0df6066ebecd60ecd..2504e0455875817438e177582f2eb987d24f1e5d 100644 (file)
@@ -508,10 +508,6 @@ static struct uart_8250_port *serial8250_setup_port(int index)
 
        up->ops = &univ8250_driver_ops;
 
-       if (IS_ENABLED(CONFIG_ALPHA_JENSEN) ||
-           (IS_ENABLED(CONFIG_ALPHA_GENERIC) && alpha_jensen()))
-               up->port.set_mctrl = alpha_jensen_set_mctrl;
-
        serial8250_set_defaults(up);
 
        return up;
index ea2e81f58eaccffc7934cac3e6dabd4b69a37273..69ac00270547c6855517865506f10c3e7e1206ca 100644 (file)
@@ -5,8 +5,6 @@
 
 obj-$(CONFIG_SERIAL_8250)              += 8250.o 8250_base.o
 8250-y                                 := 8250_core.o
-8250-$(CONFIG_ALPHA_GENERIC)           += 8250_alpha.o
-8250-$(CONFIG_ALPHA_JENSEN)            += 8250_alpha.o
 8250-$(CONFIG_SERIAL_8250_PNP)         += 8250_pnp.o
 8250_base-y                            := 8250_port.o
 8250_base-$(CONFIG_SERIAL_8250_DMA)    += 8250_dma.o
index 9446660e231bb3f9a79b5cdf1503b13377539227..008053039875a4c6d3fc9b8822491c97eadd0abe 100644 (file)
@@ -5110,9 +5110,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
        }
        if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
                ;       /* Initial ep0 maxpacket guess is right */
-       } else if ((udev->speed == USB_SPEED_FULL ||
+       } else if (((udev->speed == USB_SPEED_FULL ||
                                udev->speed == USB_SPEED_HIGH) &&
-                       (i == 8 || i == 16 || i == 32 || i == 64)) {
+                       (i == 8 || i == 16 || i == 32 || i == 64)) ||
+                       (udev->speed >= USB_SPEED_SUPER && i > 0)) {
                /* Initial guess is wrong; use the descriptor's value */
                if (udev->speed == USB_SPEED_FULL)
                        dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
index 0e1262a077aea38ed9f56b8724d748d2c64663e1..e7da2fca11a48cf9c3d53cd53d124d65a1cd751f 100644 (file)
@@ -51,13 +51,15 @@ static ssize_t disable_show(struct device *dev,
        struct usb_port *port_dev = to_usb_port(dev);
        struct usb_device *hdev = to_usb_device(dev->parent->parent);
        struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
-       struct usb_interface *intf = to_usb_interface(hub->intfdev);
+       struct usb_interface *intf = to_usb_interface(dev->parent);
        int port1 = port_dev->portnum;
        u16 portstatus, unused;
        bool disabled;
        int rc;
        struct kernfs_node *kn;
 
+       if (!hub)
+               return -ENODEV;
        hub_get(hub);
        rc = usb_autopm_get_interface(intf);
        if (rc < 0)
@@ -101,12 +103,14 @@ static ssize_t disable_store(struct device *dev, struct device_attribute *attr,
        struct usb_port *port_dev = to_usb_port(dev);
        struct usb_device *hdev = to_usb_device(dev->parent->parent);
        struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
-       struct usb_interface *intf = to_usb_interface(hub->intfdev);
+       struct usb_interface *intf = to_usb_interface(dev->parent);
        int port1 = port_dev->portnum;
        bool disabled;
        int rc;
        struct kernfs_node *kn;
 
+       if (!hub)
+               return -ENODEV;
        rc = kstrtobool(buf, &disabled);
        if (rc)
                return rc;
index 31684cdaaae3056c6cf9b16d31cc0eb4f217b7bb..100041320e8dd2e80488b7dfdc372d373ea0d251 100644 (file)
@@ -104,6 +104,27 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
        return 0;
 }
 
+void dwc3_enable_susphy(struct dwc3 *dwc, bool enable)
+{
+       u32 reg;
+
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+       if (enable && !dwc->dis_u3_susphy_quirk)
+               reg |= DWC3_GUSB3PIPECTL_SUSPHY;
+       else
+               reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
+
+       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+       if (enable && !dwc->dis_u2_susphy_quirk)
+               reg |= DWC3_GUSB2PHYCFG_SUSPHY;
+       else
+               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+
+       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+}
+
 void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode)
 {
        u32 reg;
@@ -585,11 +606,8 @@ static int dwc3_core_ulpi_init(struct dwc3 *dwc)
  */
 static int dwc3_phy_setup(struct dwc3 *dwc)
 {
-       unsigned int hw_mode;
        u32 reg;
 
-       hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
-
        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
        /*
@@ -599,21 +617,16 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
        reg &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;
 
        /*
-        * Above 1.94a, it is recommended to set DWC3_GUSB3PIPECTL_SUSPHY
-        * to '0' during coreConsultant configuration. So default value
-        * will be '0' when the core is reset. Application needs to set it
-        * to '1' after the core initialization is completed.
-        */
-       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
-               reg |= DWC3_GUSB3PIPECTL_SUSPHY;
-
-       /*
-        * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after
-        * power-on reset, and it can be set after core initialization, which is
-        * after device soft-reset during initialization.
+        * Above DWC_usb3.0 1.94a, it is recommended to set
+        * DWC3_GUSB3PIPECTL_SUSPHY to '0' during coreConsultant configuration.
+        * So default value will be '0' when the core is reset. Application
+        * needs to set it to '1' after the core initialization is completed.
+        *
+        * Similarly for DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be
+        * cleared after power-on reset, and it can be set after core
+        * initialization.
         */
-       if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
-               reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
+       reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
        if (dwc->u2ss_inp3_quirk)
                reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK;
@@ -639,9 +652,6 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->tx_de_emphasis_quirk)
                reg |= DWC3_GUSB3PIPECTL_TX_DEEPH(dwc->tx_de_emphasis);
 
-       if (dwc->dis_u3_susphy_quirk)
-               reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
-
        if (dwc->dis_del_phy_power_chg_quirk)
                reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
 
@@ -689,24 +699,15 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
        }
 
        /*
-        * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
-        * '0' during coreConsultant configuration. So default value will
-        * be '0' when the core is reset. Application needs to set it to
-        * '1' after the core initialization is completed.
-        */
-       if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A))
-               reg |= DWC3_GUSB2PHYCFG_SUSPHY;
-
-       /*
-        * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after
-        * power-on reset, and it can be set after core initialization, which is
-        * after device soft-reset during initialization.
+        * Above DWC_usb3.0 1.94a, it is recommended to set
+        * DWC3_GUSB2PHYCFG_SUSPHY to '0' during coreConsultant configuration.
+        * So default value will be '0' when the core is reset. Application
+        * needs to set it to '1' after the core initialization is completed.
+        *
+        * Similarly for DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared
+        * after power-on reset, and it can be set after core initialization.
         */
-       if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD)
-               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-
-       if (dwc->dis_u2_susphy_quirk)
-               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
+       reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
        if (dwc->dis_enblslpm_quirk)
                reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
@@ -1227,21 +1228,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
        if (ret)
                goto err_exit_phy;
 
-       if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
-           !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {
-               if (!dwc->dis_u3_susphy_quirk) {
-                       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-                       reg |= DWC3_GUSB3PIPECTL_SUSPHY;
-                       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-               }
-
-               if (!dwc->dis_u2_susphy_quirk) {
-                       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-                       reg |= DWC3_GUSB2PHYCFG_SUSPHY;
-                       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-               }
-       }
-
        dwc3_core_setup_global_control(dwc);
        dwc3_core_num_eps(dwc);
 
index 7e80dd3d466b88538f597a5f1534fd020ac23763..180dd8d29287c6851581e0a0d194a8c79c0959c2 100644 (file)
@@ -1580,6 +1580,7 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc);
 void dwc3_event_buffers_cleanup(struct dwc3 *dwc);
 
 int dwc3_core_soft_reset(struct dwc3 *dwc);
+void dwc3_enable_susphy(struct dwc3 *dwc, bool enable);
 
 #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
 int dwc3_host_init(struct dwc3 *dwc);
index 4df2661f66751bd56a3717d9f0d2705a29f07738..f94f68f1e7d2b7ccab8f565048a41950a34aa464 100644 (file)
@@ -2924,6 +2924,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
        dwc3_ep0_out_start(dwc);
 
        dwc3_gadget_enable_irq(dwc);
+       dwc3_enable_susphy(dwc, true);
 
        return 0;
 
@@ -4690,6 +4691,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
        if (!dwc->gadget)
                return;
 
+       dwc3_enable_susphy(dwc, false);
        usb_del_gadget(dwc->gadget);
        dwc3_gadget_free_endpoints(dwc);
        usb_put_gadget(dwc->gadget);
index 0204787df81d50b9291b1701c554795c3d97bca8..a171b27a7845af9ceb92d567d380a540e3ad0ef8 100644 (file)
 #include <linux/irq.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include "../host/xhci-port.h"
 #include "../host/xhci-ext-caps.h"
 #include "../host/xhci-caps.h"
+#include "../host/xhci-plat.h"
 #include "core.h"
 
 #define XHCI_HCSPARAMS1                0x4
@@ -57,6 +60,24 @@ static void dwc3_power_off_all_roothub_ports(struct dwc3 *dwc)
        }
 }
 
+static void dwc3_xhci_plat_start(struct usb_hcd *hcd)
+{
+       struct platform_device *pdev;
+       struct dwc3 *dwc;
+
+       if (!usb_hcd_is_primary_hcd(hcd))
+               return;
+
+       pdev = to_platform_device(hcd->self.controller);
+       dwc = dev_get_drvdata(pdev->dev.parent);
+
+       dwc3_enable_susphy(dwc, true);
+}
+
+static const struct xhci_plat_priv dwc3_xhci_plat_quirk = {
+       .plat_start = dwc3_xhci_plat_start,
+};
+
 static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc,
                                        int irq, char *name)
 {
@@ -167,6 +188,11 @@ int dwc3_host_init(struct dwc3 *dwc)
                }
        }
 
+       ret = platform_device_add_data(xhci, &dwc3_xhci_plat_quirk,
+                                      sizeof(struct xhci_plat_priv));
+       if (ret)
+               goto err;
+
        ret = platform_device_add(xhci);
        if (ret) {
                dev_err(dwc->dev, "failed to register xHCI device\n");
@@ -192,6 +218,7 @@ void dwc3_host_exit(struct dwc3 *dwc)
        if (dwc->sys_wakeup)
                device_init_wakeup(&dwc->xhci->dev, false);
 
+       dwc3_enable_susphy(dwc, false);
        platform_device_unregister(dwc->xhci);
        dwc->xhci = NULL;
 }
index 0ace45b66a31c417f7e6da9f811c3d8b5c736246..0e151b54aae82a3677dbbd0487d91e403f83e7b5 100644 (file)
@@ -2112,7 +2112,7 @@ unknown:
                        buf[5] = 0x01;
                        switch (ctrl->bRequestType & USB_RECIP_MASK) {
                        case USB_RECIP_DEVICE:
-                               if (w_index != 0x4 || (w_value >> 8))
+                               if (w_index != 0x4 || (w_value & 0xff))
                                        break;
                                buf[6] = w_index;
                                /* Number of ext compat interfaces */
@@ -2128,9 +2128,9 @@ unknown:
                                }
                                break;
                        case USB_RECIP_INTERFACE:
-                               if (w_index != 0x5 || (w_value >> 8))
+                               if (w_index != 0x5 || (w_value & 0xff))
                                        break;
-                               interface = w_value & 0xFF;
+                               interface = w_value >> 8;
                                if (interface >= MAX_CONFIG_INTERFACES ||
                                    !os_desc_cfg->interface[interface])
                                        break;
index f855f1fc8e5e14d253a61382a692a9173c2e2c26..a057cbedf3c9b30430eeb3a8749975e58cec54da 100644 (file)
@@ -852,6 +852,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
                                                   work);
        int ret = io_data->status;
        bool kiocb_has_eventfd = io_data->kiocb->ki_flags & IOCB_EVENTFD;
+       unsigned long flags;
 
        if (io_data->read && ret > 0) {
                kthread_use_mm(io_data->mm);
@@ -864,6 +865,11 @@ static void ffs_user_copy_worker(struct work_struct *work)
        if (io_data->ffs->ffs_eventfd && !kiocb_has_eventfd)
                eventfd_signal(io_data->ffs->ffs_eventfd);
 
+       spin_lock_irqsave(&io_data->ffs->eps_lock, flags);
+       usb_ep_free_request(io_data->ep, io_data->req);
+       io_data->req = NULL;
+       spin_unlock_irqrestore(&io_data->ffs->eps_lock, flags);
+
        if (io_data->read)
                kfree(io_data->to_free);
        ffs_free_buffer(io_data);
@@ -877,7 +883,6 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
        struct ffs_data *ffs = io_data->ffs;
 
        io_data->status = req->status ? req->status : req->actual;
-       usb_ep_free_request(_ep, req);
 
        INIT_WORK(&io_data->work, ffs_user_copy_worker);
        queue_work(ffs->io_completion_wq, &io_data->work);
@@ -3806,7 +3811,7 @@ static int ffs_func_setup(struct usb_function *f,
        __ffs_event_add(ffs, FUNCTIONFS_SETUP);
        spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
 
-       return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
+       return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
 }
 
 static bool ffs_func_req_match(struct usb_function *f,
index 7e704b2bcfd1ce5a2c28a4f318fca6633a7072f8..a4377df612f51e12760195cd1fbe89ec9c541fbe 100644 (file)
@@ -92,10 +92,10 @@ static int __uvcg_iter_item_entries(const char *page, size_t len,
 
        while (pg - page < len) {
                i = 0;
-               while (i < sizeof(buf) && (pg - page < len) &&
+               while (i < bufsize && (pg - page < len) &&
                       *pg != '\0' && *pg != '\n')
                        buf[i++] = *pg++;
-               if (i == sizeof(buf)) {
+               if (i == bufsize) {
                        ret = -EINVAL;
                        goto out_free_buf;
                }
index 4f9982ecfb583e60e0f5b9cfff4c8001b2bf598f..5cec7640e913c8bac477f67c517304bb0afe5941 100644 (file)
@@ -888,6 +888,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
        /* Check for an all 1's result which is a typical consequence
         * of dead, unclocked, or unplugged (CardBus...) devices
         */
+again:
        if (ints == ~(u32)0) {
                ohci->rh_state = OHCI_RH_HALTED;
                ohci_dbg (ohci, "device removed!\n");
@@ -982,6 +983,13 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
        }
        spin_unlock(&ohci->lock);
 
+       /* repeat until all enabled interrupts are handled */
+       if (ohci->rh_state != OHCI_RH_HALTED) {
+               ints = ohci_readl(ohci, &regs->intrstatus);
+               if (ints && (ints & ohci_readl(ohci, &regs->intrenable)))
+                       goto again;
+       }
+
        return IRQ_HANDLED;
 }
 
index 2d15386f2c504b7aa8b1798f1b41b1e81b1498c1..6475130eac4b38061ea038ad14b00a48f269d4e0 100644 (file)
@@ -8,7 +8,9 @@
 #ifndef _XHCI_PLAT_H
 #define _XHCI_PLAT_H
 
-#include "xhci.h"      /* for hcd_to_xhci() */
+struct device;
+struct platform_device;
+struct usb_hcd;
 
 struct xhci_plat_priv {
        const char *firmware_name;
index ec65b24eafa868dafe6bafaf1c3c27b16550f31d..4f59867d7117cfda924d151e35b8faeb13dd0bec 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/usb/rzv2m_usb3drd.h>
+#include "xhci.h"
 #include "xhci-plat.h"
 #include "xhci-rzv2m.h"
 
index e48412cdcb0fb5b5562afb2ce65af38a1d31840c..d3958c061a972ccbde85c07595132793e80afc94 100644 (file)
@@ -104,14 +104,18 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev)
 
        ret = tcpm->port_start(tcpm, tcpm->tcpm_port);
        if (ret)
-               goto fwnode_remove;
+               goto port_unregister;
 
        ret = tcpm->pdphy_start(tcpm, tcpm->tcpm_port);
        if (ret)
-               goto fwnode_remove;
+               goto port_stop;
 
        return 0;
 
+port_stop:
+       tcpm->port_stop(tcpm);
+port_unregister:
+       tcpm_unregister_port(tcpm->tcpm_port);
 fwnode_remove:
        fwnode_remove_software_node(tcpm->tcpc.fwnode);
 
index 6560f4fc98d5a3444ab33cc2ab29cd83890ac06b..5b7f52b74a40aa70096499e34d6c32a38c08fd48 100644 (file)
@@ -475,10 +475,8 @@ static int qcom_pmic_typec_pdphy_enable(struct pmic_typec_pdphy *pmic_typec_pdph
 
        qcom_pmic_typec_pdphy_reset_off(pmic_typec_pdphy);
 done:
-       if (ret) {
-               regulator_disable(pmic_typec_pdphy->vdd_pdphy);
+       if (ret)
                dev_err(dev, "pdphy_enable fail %d\n", ret);
-       }
 
        return ret;
 }
@@ -524,12 +522,17 @@ static int qcom_pmic_typec_pdphy_start(struct pmic_typec *tcpm,
 
        ret = pmic_typec_pdphy_reset(pmic_typec_pdphy);
        if (ret)
-               return ret;
+               goto err_disable_vdd_pdhy;
 
        for (i = 0; i < pmic_typec_pdphy->nr_irqs; i++)
                enable_irq(pmic_typec_pdphy->irq_data[i].irq);
 
        return 0;
+
+err_disable_vdd_pdhy:
+       regulator_disable(pmic_typec_pdphy->vdd_pdphy);
+
+       return ret;
 }
 
 static void qcom_pmic_typec_pdphy_stop(struct pmic_typec *tcpm)
index ab6ed6111ed05ce44f1fc94202299faf143bd79c..8a1af08f71b6450710e4ae7ff2e891f490a036ca 100644 (file)
@@ -1564,8 +1564,12 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
 static void tcpm_queue_vdm_unlocked(struct tcpm_port *port, const u32 header,
                                    const u32 *data, int cnt, enum tcpm_transmit_type tx_sop_type)
 {
+       if (port->state != SRC_READY && port->state != SNK_READY &&
+           port->state != SRC_VDM_IDENTITY_REQUEST)
+               return;
+
        mutex_lock(&port->lock);
-       tcpm_queue_vdm(port, header, data, cnt, TCPC_TX_SOP);
+       tcpm_queue_vdm(port, header, data, cnt, tx_sop_type);
        mutex_unlock(&port->lock);
 }
 
@@ -1580,7 +1584,8 @@ static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt)
        port->partner_ident.cert_stat = p[VDO_INDEX_CSTAT];
        port->partner_ident.product = product;
 
-       typec_partner_set_identity(port->partner);
+       if (port->partner)
+               typec_partner_set_identity(port->partner);
 
        tcpm_log(port, "Identity: %04x:%04x.%04x",
                 PD_IDH_VID(vdo),
@@ -1742,6 +1747,9 @@ static void tcpm_register_partner_altmodes(struct tcpm_port *port)
        struct typec_altmode *altmode;
        int i;
 
+       if (!port->partner)
+               return;
+
        for (i = 0; i < modep->altmodes; i++) {
                altmode = typec_partner_register_altmode(port->partner,
                                                &modep->altmode_desc[i]);
@@ -2996,7 +3004,7 @@ static int tcpm_register_source_caps(struct tcpm_port *port)
 {
        struct usb_power_delivery_desc desc = { port->negotiated_rev };
        struct usb_power_delivery_capabilities_desc caps = { };
-       struct usb_power_delivery_capabilities *cap;
+       struct usb_power_delivery_capabilities *cap = port->partner_source_caps;
 
        if (!port->partner_pd)
                port->partner_pd = usb_power_delivery_register(NULL, &desc);
@@ -3006,6 +3014,9 @@ static int tcpm_register_source_caps(struct tcpm_port *port)
        memcpy(caps.pdo, port->source_caps, sizeof(u32) * port->nr_source_caps);
        caps.role = TYPEC_SOURCE;
 
+       if (cap)
+               usb_power_delivery_unregister_capabilities(cap);
+
        cap = usb_power_delivery_register_capabilities(port->partner_pd, &caps);
        if (IS_ERR(cap))
                return PTR_ERR(cap);
@@ -4231,7 +4242,10 @@ static int tcpm_init_vconn(struct tcpm_port *port)
 
 static void tcpm_typec_connect(struct tcpm_port *port)
 {
+       struct typec_partner *partner;
+
        if (!port->connected) {
+               port->connected = true;
                /* Make sure we don't report stale identity information */
                memset(&port->partner_ident, 0, sizeof(port->partner_ident));
                port->partner_desc.usb_pd = port->pd_capable;
@@ -4241,9 +4255,13 @@ static void tcpm_typec_connect(struct tcpm_port *port)
                        port->partner_desc.accessory = TYPEC_ACCESSORY_AUDIO;
                else
                        port->partner_desc.accessory = TYPEC_ACCESSORY_NONE;
-               port->partner = typec_register_partner(port->typec_port,
-                                                      &port->partner_desc);
-               port->connected = true;
+               partner = typec_register_partner(port->typec_port, &port->partner_desc);
+               if (IS_ERR(partner)) {
+                       dev_err(port->dev, "Failed to register partner (%ld)\n", PTR_ERR(partner));
+                       return;
+               }
+
+               port->partner = partner;
                typec_partner_set_usb_power_delivery(port->partner, port->partner_pd);
        }
 }
@@ -4323,9 +4341,11 @@ static void tcpm_typec_disconnect(struct tcpm_port *port)
        port->plug_prime = NULL;
        port->cable = NULL;
        if (port->connected) {
-               typec_partner_set_usb_power_delivery(port->partner, NULL);
-               typec_unregister_partner(port->partner);
-               port->partner = NULL;
+               if (port->partner) {
+                       typec_partner_set_usb_power_delivery(port->partner, NULL);
+                       typec_unregister_partner(port->partner);
+                       port->partner = NULL;
+               }
                port->connected = false;
        }
 }
@@ -4549,6 +4569,9 @@ static enum typec_cc_status tcpm_pwr_opmode_to_rp(enum typec_pwr_opmode opmode)
 
 static void tcpm_set_initial_svdm_version(struct tcpm_port *port)
 {
+       if (!port->partner)
+               return;
+
        switch (port->negotiated_rev) {
        case PD_REV30:
                break;
@@ -5605,6 +5628,7 @@ static void run_state_machine(struct tcpm_port *port)
                break;
        case PORT_RESET:
                tcpm_reset_port(port);
+               port->pd_events = 0;
                if (port->self_powered)
                        tcpm_set_cc(port, TYPEC_CC_OPEN);
                else
index 047855033d32f73f054a074452622499d5cf983c..a97ceb105cd8dd02060afa539acd8ee6749357cb 100644 (file)
 #include "cache.h"
 #include "fid.h"
 
-static void v9fs_upload_to_server(struct netfs_io_subrequest *subreq)
+/*
+ * Writeback calls this when it finds a folio that needs uploading.  This isn't
+ * called if writeback only has copy-to-cache to deal with.
+ */
+static void v9fs_begin_writeback(struct netfs_io_request *wreq)
 {
-       struct p9_fid *fid = subreq->rreq->netfs_priv;
-       int err, len;
-
-       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
-       len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err);
-       netfs_write_subrequest_terminated(subreq, len ?: err, false);
-}
+       struct p9_fid *fid;
 
-static void v9fs_upload_to_server_worker(struct work_struct *work)
-{
-       struct netfs_io_subrequest *subreq =
-               container_of(work, struct netfs_io_subrequest, work);
+       fid = v9fs_fid_find_inode(wreq->inode, true, INVALID_UID, true);
+       if (!fid) {
+               WARN_ONCE(1, "folio expected an open fid inode->i_ino=%lx\n",
+                         wreq->inode->i_ino);
+               return;
+       }
 
-       v9fs_upload_to_server(subreq);
+       wreq->wsize = fid->clnt->msize - P9_IOHDRSZ;
+       if (fid->iounit)
+               wreq->wsize = min(wreq->wsize, fid->iounit);
+       wreq->netfs_priv = fid;
+       wreq->io_streams[0].avail = true;
 }
 
 /*
- * Set up write requests for a writeback slice.  We need to add a write request
- * for each write we want to make.
+ * Issue a subrequest to write to the server.
  */
-static void v9fs_create_write_requests(struct netfs_io_request *wreq, loff_t start, size_t len)
+static void v9fs_issue_write(struct netfs_io_subrequest *subreq)
 {
-       struct netfs_io_subrequest *subreq;
+       struct p9_fid *fid = subreq->rreq->netfs_priv;
+       int err, len;
 
-       subreq = netfs_create_write_request(wreq, NETFS_UPLOAD_TO_SERVER,
-                                           start, len, v9fs_upload_to_server_worker);
-       if (subreq)
-               netfs_queue_write_request(subreq);
+       len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err);
+       netfs_write_subrequest_terminated(subreq, len ?: err, false);
 }
 
 /**
@@ -87,12 +89,16 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
 {
        struct p9_fid *fid;
        bool writing = (rreq->origin == NETFS_READ_FOR_WRITE ||
-                       rreq->origin == NETFS_WRITEBACK ||
                        rreq->origin == NETFS_WRITETHROUGH ||
-                       rreq->origin == NETFS_LAUNDER_WRITE ||
                        rreq->origin == NETFS_UNBUFFERED_WRITE ||
                        rreq->origin == NETFS_DIO_WRITE);
 
+       if (rreq->origin == NETFS_WRITEBACK)
+               return 0; /* We don't get the write handle until we find we
+                          * have actually dirty data and not just
+                          * copy-to-cache data.
+                          */
+
        if (file) {
                fid = file->private_data;
                if (!fid)
@@ -104,6 +110,10 @@ static int v9fs_init_request(struct netfs_io_request *rreq, struct file *file)
                        goto no_fid;
        }
 
+       rreq->wsize = fid->clnt->msize - P9_IOHDRSZ;
+       if (fid->iounit)
+               rreq->wsize = min(rreq->wsize, fid->iounit);
+
        /* we might need to read from a fid that was opened write-only
         * for read-modify-write of page cache, use the writeback fid
         * for that */
@@ -132,7 +142,8 @@ const struct netfs_request_ops v9fs_req_ops = {
        .init_request           = v9fs_init_request,
        .free_request           = v9fs_free_request,
        .issue_read             = v9fs_issue_read,
-       .create_write_requests  = v9fs_create_write_requests,
+       .begin_writeback        = v9fs_begin_writeback,
+       .issue_write            = v9fs_issue_write,
 };
 
 const struct address_space_operations v9fs_addr_operations = {
@@ -141,7 +152,6 @@ const struct address_space_operations v9fs_addr_operations = {
        .dirty_folio            = netfs_dirty_folio,
        .release_folio          = netfs_release_folio,
        .invalidate_folio       = netfs_invalidate_folio,
-       .launder_folio          = netfs_launder_folio,
        .direct_IO              = noop_direct_IO,
        .writepages             = netfs_writepages,
 };
index ef2cc8f565d25b15e086d2fc64c6f565bac7a16b..c3f0c45ae9a9b6f6582accd6e9365862808fb7e1 100644 (file)
@@ -54,7 +54,6 @@ const struct address_space_operations afs_file_aops = {
        .read_folio     = netfs_read_folio,
        .readahead      = netfs_readahead,
        .dirty_folio    = netfs_dirty_folio,
-       .launder_folio  = netfs_launder_folio,
        .release_folio  = netfs_release_folio,
        .invalidate_folio = netfs_invalidate_folio,
        .migrate_folio  = filemap_migrate_folio,
@@ -354,7 +353,7 @@ static int afs_init_request(struct netfs_io_request *rreq, struct file *file)
        if (file)
                rreq->netfs_priv = key_get(afs_file_key(file));
        rreq->rsize = 256 * 1024;
-       rreq->wsize = 256 * 1024;
+       rreq->wsize = 256 * 1024 * 1024;
        return 0;
 }
 
@@ -369,6 +368,7 @@ static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
 static void afs_free_request(struct netfs_io_request *rreq)
 {
        key_put(rreq->netfs_priv);
+       afs_put_wb_key(rreq->netfs_priv2);
 }
 
 static void afs_update_i_size(struct inode *inode, loff_t new_i_size)
@@ -400,7 +400,9 @@ const struct netfs_request_ops afs_req_ops = {
        .issue_read             = afs_issue_read,
        .update_i_size          = afs_update_i_size,
        .invalidate_cache       = afs_netfs_invalidate_cache,
-       .create_write_requests  = afs_create_write_requests,
+       .begin_writeback        = afs_begin_writeback,
+       .prepare_write          = afs_prepare_write,
+       .issue_write            = afs_issue_write,
 };
 
 static void afs_add_open_mmap(struct afs_vnode *vnode)
index 6ce5a612937c61e2021b32cad1f68a22b7c501ca..6e1d3c4daf72c6578b173b32364a1e136c7b6fec 100644 (file)
@@ -916,7 +916,6 @@ struct afs_operation {
                        loff_t  pos;
                        loff_t  size;
                        loff_t  i_size;
-                       bool    laundering;     /* Laundering page, PG_writeback not set */
                } store;
                struct {
                        struct iattr    *attr;
@@ -1599,11 +1598,14 @@ extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *);
 /*
  * write.c
  */
+void afs_prepare_write(struct netfs_io_subrequest *subreq);
+void afs_issue_write(struct netfs_io_subrequest *subreq);
+void afs_begin_writeback(struct netfs_io_request *wreq);
+void afs_retry_request(struct netfs_io_request *wreq, struct netfs_io_stream *stream);
 extern int afs_writepages(struct address_space *, struct writeback_control *);
 extern int afs_fsync(struct file *, loff_t, loff_t, int);
 extern vm_fault_t afs_page_mkwrite(struct vm_fault *vmf);
 extern void afs_prune_wb_keys(struct afs_vnode *);
-void afs_create_write_requests(struct netfs_io_request *wreq, loff_t start, size_t len);
 
 /*
  * xattr.c
index ed04bd1eeae89793219aacd1ada6efb61aa6ba03..ed09d4d4c2112189bfa724d577769e5ae8f15bdd 100644 (file)
@@ -541,11 +541,13 @@ pick_server:
                    test_bit(AFS_SE_EXCLUDED, &se->flags) ||
                    !test_bit(AFS_SERVER_FL_RESPONDING, &s->flags))
                        continue;
-               es = op->server_states->endpoint_state;
+               es = op->server_states[i].endpoint_state;
                sal = es->addresses;
 
                afs_get_address_preferences_rcu(op->net, sal);
                for (j = 0; j < sal->nr_addrs; j++) {
+                       if (es->failed_set & (1 << j))
+                               continue;
                        if (!sal->addrs[j].peer)
                                continue;
                        if (sal->addrs[j].prio > best_prio) {
@@ -605,6 +607,8 @@ iterate_address:
        best_prio = -1;
        addr_index = 0;
        for (i = 0; i < alist->nr_addrs; i++) {
+               if (!(set & (1 << i)))
+                       continue;
                if (alist->addrs[i].prio > best_prio) {
                        addr_index = i;
                        best_prio = alist->addrs[i].prio;
@@ -674,7 +678,7 @@ no_more_servers:
        for (i = 0; i < op->server_list->nr_servers; i++) {
                struct afs_endpoint_state *estate;
 
-               estate = op->server_states->endpoint_state;
+               estate = op->server_states[i].endpoint_state;
                error = READ_ONCE(estate->error);
                if (error < 0)
                        afs_op_accumulate_error(op, error, estate->abort_code);
index 32a53fc8dfb26b292c0817155a7c9d387d66064d..bef8af12ebe27fbddb131efcc65e94fc0303f62d 100644 (file)
@@ -365,9 +365,9 @@ static void afs_zap_data(struct afs_vnode *vnode)
         * written back in a regular file and completely discard the pages in a
         * directory or symlink */
        if (S_ISREG(vnode->netfs.inode.i_mode))
-               invalidate_remote_inode(&vnode->netfs.inode);
+               filemap_invalidate_inode(&vnode->netfs.inode, true, 0, LLONG_MAX);
        else
-               invalidate_inode_pages2(vnode->netfs.inode.i_mapping);
+               filemap_invalidate_inode(&vnode->netfs.inode, false, 0, LLONG_MAX);
 }
 
 /*
index 74402d95a88434bb58e1e3989d296c11d8f9861d..e959640694c25c67f97b2b79cb8065de3d68f714 100644 (file)
@@ -29,43 +29,39 @@ static void afs_pages_written_back(struct afs_vnode *vnode, loff_t start, unsign
 
 /*
  * Find a key to use for the writeback.  We cached the keys used to author the
- * writes on the vnode.  *_wbk will contain the last writeback key used or NULL
- * and we need to start from there if it's set.
+ * writes on the vnode.  wreq->netfs_priv2 will contain the last writeback key
+ * record used or NULL and we need to start from there if it's set.
+ * wreq->netfs_priv will be set to the key itself or NULL.
  */
-static int afs_get_writeback_key(struct afs_vnode *vnode,
-                                struct afs_wb_key **_wbk)
+static void afs_get_writeback_key(struct netfs_io_request *wreq)
 {
-       struct afs_wb_key *wbk = NULL;
-       struct list_head *p;
-       int ret = -ENOKEY, ret2;
+       struct afs_wb_key *wbk, *old = wreq->netfs_priv2;
+       struct afs_vnode *vnode = AFS_FS_I(wreq->inode);
+
+       key_put(wreq->netfs_priv);
+       wreq->netfs_priv = NULL;
+       wreq->netfs_priv2 = NULL;
 
        spin_lock(&vnode->wb_lock);
-       if (*_wbk)
-               p = (*_wbk)->vnode_link.next;
+       if (old)
+               wbk = list_next_entry(old, vnode_link);
        else
-               p = vnode->wb_keys.next;
+               wbk = list_first_entry(&vnode->wb_keys, struct afs_wb_key, vnode_link);
 
-       while (p != &vnode->wb_keys) {
-               wbk = list_entry(p, struct afs_wb_key, vnode_link);
+       list_for_each_entry_from(wbk, &vnode->wb_keys, vnode_link) {
                _debug("wbk %u", key_serial(wbk->key));
-               ret2 = key_validate(wbk->key);
-               if (ret2 == 0) {
+               if (key_validate(wbk->key) == 0) {
                        refcount_inc(&wbk->usage);
+                       wreq->netfs_priv = key_get(wbk->key);
+                       wreq->netfs_priv2 = wbk;
                        _debug("USE WB KEY %u", key_serial(wbk->key));
                        break;
                }
-
-               wbk = NULL;
-               if (ret == -ENOKEY)
-                       ret = ret2;
-               p = p->next;
        }
 
        spin_unlock(&vnode->wb_lock);
-       if (*_wbk)
-               afs_put_wb_key(*_wbk);
-       *_wbk = wbk;
-       return 0;
+
+       afs_put_wb_key(old);
 }
 
 static void afs_store_data_success(struct afs_operation *op)
@@ -75,8 +71,7 @@ static void afs_store_data_success(struct afs_operation *op)
        op->ctime = op->file[0].scb.status.mtime_client;
        afs_vnode_commit_status(op, &op->file[0]);
        if (!afs_op_error(op)) {
-               if (!op->store.laundering)
-                       afs_pages_written_back(vnode, op->store.pos, op->store.size);
+               afs_pages_written_back(vnode, op->store.pos, op->store.size);
                afs_stat_v(vnode, n_stores);
                atomic_long_add(op->store.size, &afs_v2net(vnode)->n_store_bytes);
        }
@@ -89,113 +84,125 @@ static const struct afs_operation_ops afs_store_data_operation = {
 };
 
 /*
- * write to a file
+ * Prepare a subrequest to write to the server.  This sets the max_len
+ * parameter.
+ */
+void afs_prepare_write(struct netfs_io_subrequest *subreq)
+{
+       //if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
+       //      subreq->max_len = 512 * 1024;
+       //else
+       subreq->max_len = 256 * 1024 * 1024;
+}
+
+/*
+ * Issue a subrequest to write to the server.
  */
-static int afs_store_data(struct afs_vnode *vnode, struct iov_iter *iter, loff_t pos,
-                         bool laundering)
+static void afs_issue_write_worker(struct work_struct *work)
 {
+       struct netfs_io_subrequest *subreq = container_of(work, struct netfs_io_subrequest, work);
+       struct netfs_io_request *wreq = subreq->rreq;
        struct afs_operation *op;
-       struct afs_wb_key *wbk = NULL;
-       loff_t size = iov_iter_count(iter);
+       struct afs_vnode *vnode = AFS_FS_I(wreq->inode);
+       unsigned long long pos = subreq->start + subreq->transferred;
+       size_t len = subreq->len - subreq->transferred;
        int ret = -ENOKEY;
 
-       _enter("%s{%llx:%llu.%u},%llx,%llx",
+       _enter("R=%x[%x],%s{%llx:%llu.%u},%llx,%zx",
+              wreq->debug_id, subreq->debug_index,
               vnode->volume->name,
               vnode->fid.vid,
               vnode->fid.vnode,
               vnode->fid.unique,
-              size, pos);
+              pos, len);
 
-       ret = afs_get_writeback_key(vnode, &wbk);
-       if (ret) {
-               _leave(" = %d [no keys]", ret);
-               return ret;
-       }
+#if 0 // Error injection
+       if (subreq->debug_index == 3)
+               return netfs_write_subrequest_terminated(subreq, -ENOANO, false);
 
-       op = afs_alloc_operation(wbk->key, vnode->volume);
-       if (IS_ERR(op)) {
-               afs_put_wb_key(wbk);
-               return -ENOMEM;
+       if (!test_bit(NETFS_SREQ_RETRYING, &subreq->flags)) {
+               set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
+               return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
        }
+#endif
+
+       op = afs_alloc_operation(wreq->netfs_priv, vnode->volume);
+       if (IS_ERR(op))
+               return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
 
        afs_op_set_vnode(op, 0, vnode);
-       op->file[0].dv_delta = 1;
+       op->file[0].dv_delta    = 1;
        op->file[0].modification = true;
-       op->store.pos = pos;
-       op->store.size = size;
-       op->store.laundering = laundering;
-       op->flags |= AFS_OPERATION_UNINTR;
-       op->ops = &afs_store_data_operation;
+       op->store.pos           = pos;
+       op->store.size          = len;
+       op->flags               |= AFS_OPERATION_UNINTR;
+       op->ops                 = &afs_store_data_operation;
 
-try_next_key:
        afs_begin_vnode_operation(op);
 
-       op->store.write_iter iter;
-       op->store.i_size = max(pos + size, vnode->netfs.remote_i_size);
-       op->mtime = inode_get_mtime(&vnode->netfs.inode);
+       op->store.write_iter    = &subreq->io_iter;
+       op->store.i_size        = umax(pos + len, vnode->netfs.remote_i_size);
+       op->mtime               = inode_get_mtime(&vnode->netfs.inode);
 
        afs_wait_for_operation(op);
-
-       switch (afs_op_error(op)) {
+       ret = afs_put_operation(op);
+       switch (ret) {
        case -EACCES:
        case -EPERM:
        case -ENOKEY:
        case -EKEYEXPIRED:
        case -EKEYREJECTED:
        case -EKEYREVOKED:
-               _debug("next");
-
-               ret = afs_get_writeback_key(vnode, &wbk);
-               if (ret == 0) {
-                       key_put(op->key);
-                       op->key = key_get(wbk->key);
-                       goto try_next_key;
-               }
+               /* If there are more keys we can try, use the retry algorithm
+                * to rotate the keys.
+                */
+               if (wreq->netfs_priv2)
+                       set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
                break;
        }
 
-       afs_put_wb_key(wbk);
-       _leave(" = %d", afs_op_error(op));
-       return afs_put_operation(op);
+       netfs_write_subrequest_terminated(subreq, ret < 0 ? ret : subreq->len, false);
 }
 
-static void afs_upload_to_server(struct netfs_io_subrequest *subreq)
+void afs_issue_write(struct netfs_io_subrequest *subreq)
 {
-       struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
-       ssize_t ret;
-
-       _enter("%x[%x],%zx",
-              subreq->rreq->debug_id, subreq->debug_index, subreq->io_iter.count);
-
-       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
-       ret = afs_store_data(vnode, &subreq->io_iter, subreq->start,
-                            subreq->rreq->origin == NETFS_LAUNDER_WRITE);
-       netfs_write_subrequest_terminated(subreq, ret < 0 ? ret : subreq->len,
-                                         false);
+       subreq->work.func = afs_issue_write_worker;
+       if (!queue_work(system_unbound_wq, &subreq->work))
+               WARN_ON_ONCE(1);
 }
 
-static void afs_upload_to_server_worker(struct work_struct *work)
+/*
+ * Writeback calls this when it finds a folio that needs uploading.  This isn't
+ * called if writeback only has copy-to-cache to deal with.
+ */
+void afs_begin_writeback(struct netfs_io_request *wreq)
 {
-       struct netfs_io_subrequest *subreq =
-               container_of(work, struct netfs_io_subrequest, work);
-
-       afs_upload_to_server(subreq);
+       afs_get_writeback_key(wreq);
+       wreq->io_streams[0].avail = true;
 }
 
 /*
- * Set up write requests for a writeback slice.  We need to add a write request
- * for each write we want to make.
+ * Prepare to retry the writes in request.  Use this to try rotating the
+ * available writeback keys.
  */
-void afs_create_write_requests(struct netfs_io_request *wreq, loff_t start, size_t len)
+void afs_retry_request(struct netfs_io_request *wreq, struct netfs_io_stream *stream)
 {
-       struct netfs_io_subrequest *subreq;
-
-       _enter("%x,%llx-%llx", wreq->debug_id, start, start + len);
+       struct netfs_io_subrequest *subreq =
+               list_first_entry(&stream->subrequests,
+                                struct netfs_io_subrequest, rreq_link);
 
-       subreq = netfs_create_write_request(wreq, NETFS_UPLOAD_TO_SERVER,
-                                           start, len, afs_upload_to_server_worker);
-       if (subreq)
-               netfs_queue_write_request(subreq);
+       switch (subreq->error) {
+       case -EACCES:
+       case -EPERM:
+       case -ENOKEY:
+       case -EKEYEXPIRED:
+       case -EKEYREJECTED:
+       case -EKEYREVOKED:
+               afs_get_writeback_key(wreq);
+               if (!wreq->netfs_priv)
+                       stream->failed = true;
+               break;
+       }
 }
 
 /*
index 0f4f531c97800c648437fb2eb7409ccc2b198536..6ed5507cd33099047b7da049f0b13ae1b31d3895 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -122,7 +122,7 @@ struct kioctx {
        unsigned long           mmap_base;
        unsigned long           mmap_size;
 
-       struct page             **ring_pages;
+       struct folio            **ring_folios;
        long                    nr_pages;
 
        struct rcu_work         free_rwork;     /* see free_ioctx() */
@@ -160,7 +160,7 @@ struct kioctx {
                spinlock_t      completion_lock;
        } ____cacheline_aligned_in_smp;
 
-       struct page             *internal_pages[AIO_RING_PAGES];
+       struct folio            *internal_folios[AIO_RING_PAGES];
        struct file             *aio_ring_file;
 
        unsigned                id;
@@ -334,19 +334,20 @@ static void aio_free_ring(struct kioctx *ctx)
        put_aio_ring_file(ctx);
 
        for (i = 0; i < ctx->nr_pages; i++) {
-               struct page *page;
-               pr_debug("pid(%d) [%d] page->count=%d\n", current->pid, i,
-                               page_count(ctx->ring_pages[i]));
-               page = ctx->ring_pages[i];
-               if (!page)
+               struct folio *folio = ctx->ring_folios[i];
+
+               if (!folio)
                        continue;
-               ctx->ring_pages[i] = NULL;
-               put_page(page);
+
+               pr_debug("pid(%d) [%d] folio->count=%d\n", current->pid, i,
+                        folio_ref_count(folio));
+               ctx->ring_folios[i] = NULL;
+               folio_put(folio);
        }
 
-       if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) {
-               kfree(ctx->ring_pages);
-               ctx->ring_pages = NULL;
+       if (ctx->ring_folios && ctx->ring_folios != ctx->internal_folios) {
+               kfree(ctx->ring_folios);
+               ctx->ring_folios = NULL;
        }
 }
 
@@ -441,7 +442,7 @@ static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
        idx = src->index;
        if (idx < (pgoff_t)ctx->nr_pages) {
                /* Make sure the old folio hasn't already been changed */
-               if (ctx->ring_pages[idx] != &src->page)
+               if (ctx->ring_folios[idx] != src)
                        rc = -EAGAIN;
        } else
                rc = -EINVAL;
@@ -465,8 +466,8 @@ static int aio_migrate_folio(struct address_space *mapping, struct folio *dst,
         */
        spin_lock_irqsave(&ctx->completion_lock, flags);
        folio_migrate_copy(dst, src);
-       BUG_ON(ctx->ring_pages[idx] != &src->page);
-       ctx->ring_pages[idx] = &dst->page;
+       BUG_ON(ctx->ring_folios[idx] != src);
+       ctx->ring_folios[idx] = dst;
        spin_unlock_irqrestore(&ctx->completion_lock, flags);
 
        /* The old folio is no longer accessible. */
@@ -516,28 +517,30 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)
        nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring))
                        / sizeof(struct io_event);
 
-       ctx->ring_pages = ctx->internal_pages;
+       ctx->ring_folios = ctx->internal_folios;
        if (nr_pages > AIO_RING_PAGES) {
-               ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
-                                         GFP_KERNEL);
-               if (!ctx->ring_pages) {
+               ctx->ring_folios = kcalloc(nr_pages, sizeof(struct folio *),
+                                          GFP_KERNEL);
+               if (!ctx->ring_folios) {
                        put_aio_ring_file(ctx);
                        return -ENOMEM;
                }
        }
 
        for (i = 0; i < nr_pages; i++) {
-               struct page *page;
-               page = find_or_create_page(file->f_mapping,
-                                          i, GFP_USER | __GFP_ZERO);
-               if (!page)
+               struct folio *folio;
+
+               folio = __filemap_get_folio(file->f_mapping, i,
+                                           FGP_LOCK | FGP_ACCESSED | FGP_CREAT,
+                                           GFP_USER | __GFP_ZERO);
+               if (IS_ERR(folio))
                        break;
-               pr_debug("pid(%d) page[%d]->count=%d\n",
-                        current->pid, i, page_count(page));
-               SetPageUptodate(page);
-               unlock_page(page);
 
-               ctx->ring_pages[i] = page;
+               pr_debug("pid(%d) [%d] folio->count=%d\n", current->pid, i,
+                        folio_ref_count(folio));
+               folio_end_read(folio, true);
+
+               ctx->ring_folios[i] = folio;
        }
        ctx->nr_pages = i;
 
@@ -570,7 +573,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)
        ctx->user_id = ctx->mmap_base;
        ctx->nr_events = nr_events; /* trusted copy */
 
-       ring = page_address(ctx->ring_pages[0]);
+       ring = folio_address(ctx->ring_folios[0]);
        ring->nr = nr_events;   /* user copy */
        ring->id = ~0U;
        ring->head = ring->tail = 0;
@@ -578,7 +581,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events)
        ring->compat_features = AIO_RING_COMPAT_FEATURES;
        ring->incompat_features = AIO_RING_INCOMPAT_FEATURES;
        ring->header_length = sizeof(struct aio_ring);
-       flush_dcache_page(ctx->ring_pages[0]);
+       flush_dcache_folio(ctx->ring_folios[0]);
 
        return 0;
 }
@@ -689,9 +692,9 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
 
                                        /* While kioctx setup is in progress,
                                         * we are protected from page migration
-                                        * changes ring_pages by ->ring_lock.
+                                        * changes ring_folios by ->ring_lock.
                                         */
-                                       ring = page_address(ctx->ring_pages[0]);
+                                       ring = folio_address(ctx->ring_folios[0]);
                                        ring->id = ctx->id;
                                        return 0;
                                }
@@ -1033,7 +1036,7 @@ static void user_refill_reqs_available(struct kioctx *ctx)
                 * against ctx->completed_events below will make sure we do the
                 * safe/right thing.
                 */
-               ring = page_address(ctx->ring_pages[0]);
+               ring = folio_address(ctx->ring_folios[0]);
                head = ring->head;
 
                refill_reqs_available(ctx, head, ctx->tail);
@@ -1145,12 +1148,12 @@ static void aio_complete(struct aio_kiocb *iocb)
        if (++tail >= ctx->nr_events)
                tail = 0;
 
-       ev_page = page_address(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
+       ev_page = folio_address(ctx->ring_folios[pos / AIO_EVENTS_PER_PAGE]);
        event = ev_page + pos % AIO_EVENTS_PER_PAGE;
 
        *event = iocb->ki_res;
 
-       flush_dcache_page(ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE]);
+       flush_dcache_folio(ctx->ring_folios[pos / AIO_EVENTS_PER_PAGE]);
 
        pr_debug("%p[%u]: %p: %p %Lx %Lx %Lx\n", ctx, tail, iocb,
                 (void __user *)(unsigned long)iocb->ki_res.obj,
@@ -1163,10 +1166,10 @@ static void aio_complete(struct aio_kiocb *iocb)
 
        ctx->tail = tail;
 
-       ring = page_address(ctx->ring_pages[0]);
+       ring = folio_address(ctx->ring_folios[0]);
        head = ring->head;
        ring->tail = tail;
-       flush_dcache_page(ctx->ring_pages[0]);
+       flush_dcache_folio(ctx->ring_folios[0]);
 
        ctx->completed_events++;
        if (ctx->completed_events > 1)
@@ -1238,8 +1241,8 @@ static long aio_read_events_ring(struct kioctx *ctx,
        sched_annotate_sleep();
        mutex_lock(&ctx->ring_lock);
 
-       /* Access to ->ring_pages here is protected by ctx->ring_lock. */
-       ring = page_address(ctx->ring_pages[0]);
+       /* Access to ->ring_folios here is protected by ctx->ring_lock. */
+       ring = folio_address(ctx->ring_folios[0]);
        head = ring->head;
        tail = ring->tail;
 
@@ -1260,20 +1263,20 @@ static long aio_read_events_ring(struct kioctx *ctx,
        while (ret < nr) {
                long avail;
                struct io_event *ev;
-               struct page *page;
+               struct folio *folio;
 
                avail = (head <= tail ?  tail : ctx->nr_events) - head;
                if (head == tail)
                        break;
 
                pos = head + AIO_EVENTS_OFFSET;
-               page = ctx->ring_pages[pos / AIO_EVENTS_PER_PAGE];
+               folio = ctx->ring_folios[pos / AIO_EVENTS_PER_PAGE];
                pos %= AIO_EVENTS_PER_PAGE;
 
                avail = min(avail, nr - ret);
                avail = min_t(long, avail, AIO_EVENTS_PER_PAGE - pos);
 
-               ev = page_address(page);
+               ev = folio_address(folio);
                copy_ret = copy_to_user(event + ret, ev + pos,
                                        sizeof(*ev) * avail);
 
@@ -1287,9 +1290,9 @@ static long aio_read_events_ring(struct kioctx *ctx,
                head %= ctx->nr_events;
        }
 
-       ring = page_address(ctx->ring_pages[0]);
+       ring = folio_address(ctx->ring_folios[0]);
        ring->head = head;
-       flush_dcache_page(ctx->ring_pages[0]);
+       flush_dcache_folio(ctx->ring_folios[0]);
 
        pr_debug("%li  h%u t%u\n", ret, head, tail);
 out:
index 0496cb5b6eab9a56a20c4243e348235875970d92..42bd1cb7c9cdd4af9db8617d8fbc7f7b8aa254a8 100644 (file)
@@ -148,6 +148,38 @@ struct file *anon_inode_getfile(const char *name,
 }
 EXPORT_SYMBOL_GPL(anon_inode_getfile);
 
+/**
+ * anon_inode_getfile_fmode - creates a new file instance by hooking it up to an
+ *                      anonymous inode, and a dentry that describe the "class"
+ *                      of the file
+ *
+ * @name:    [in]    name of the "class" of the new file
+ * @fops:    [in]    file operations for the new file
+ * @priv:    [in]    private data for the new file (will be file's private_data)
+ * @flags:   [in]    flags
+ * @f_mode:  [in]    fmode
+ *
+ * Creates a new file by hooking it on a single inode. This is useful for files
+ * that do not need to have a full-fledged inode in order to operate correctly.
+ * All the files created with anon_inode_getfile() will share a single inode,
+ * hence saving memory and avoiding code duplication for the file/inode/dentry
+ * setup. Allows setting the fmode. Returns the newly created file* or an error
+ * pointer.
+ */
+struct file *anon_inode_getfile_fmode(const char *name,
+                               const struct file_operations *fops,
+                               void *priv, int flags, fmode_t f_mode)
+{
+       struct file *file;
+
+       file = __anon_inode_getfile(name, fops, priv, flags, NULL, false);
+       if (!IS_ERR(file))
+               file->f_mode |= f_mode;
+
+       return file;
+}
+EXPORT_SYMBOL_GPL(anon_inode_getfile_fmode);
+
 /**
  * anon_inode_create_getfile - Like anon_inode_getfile(), but creates a new
  *                             !S_PRIVATE anon inode rather than reuse the
@@ -271,6 +303,7 @@ int anon_inode_create_getfd(const char *name, const struct file_operations *fops
        return __anon_inode_getfd(name, fops, priv, flags, context_inode, true);
 }
 
+
 static int __init anon_inode_init(void)
 {
        anon_inode_mnt = kern_mount(&anon_inode_fs_type);
index 4ff56fa4d539201e648f28a9225e9d71a59907f0..534ba2b02bd6527fa3f05665c88b8335c351bab3 100644 (file)
@@ -244,10 +244,10 @@ int bch2_alloc_v4_invalid(struct bch_fs *c, struct bkey_s_c k,
        struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
        int ret = 0;
 
-       bkey_fsck_err_on(alloc_v4_u64s(a.v) > bkey_val_u64s(k.k), c, err,
+       bkey_fsck_err_on(alloc_v4_u64s_noerror(a.v) > bkey_val_u64s(k.k), c, err,
                         alloc_v4_val_size_bad,
                         "bad val size (%u > %zu)",
-                        alloc_v4_u64s(a.v), bkey_val_u64s(k.k));
+                        alloc_v4_u64s_noerror(a.v), bkey_val_u64s(k.k));
 
        bkey_fsck_err_on(!BCH_ALLOC_V4_BACKPOINTERS_START(a.v) &&
                         BCH_ALLOC_V4_NR_BACKPOINTERS(a.v), c, err,
index 052b2fac25d693c7dddba5077fc9caeec2d246dd..2790e516383d59dccf7a75f0782abe797e1f51bc 100644 (file)
@@ -126,13 +126,17 @@ static inline struct bpos alloc_freespace_pos(struct bpos pos, struct bch_alloc_
        return pos;
 }
 
-static inline unsigned alloc_v4_u64s(const struct bch_alloc_v4 *a)
+static inline unsigned alloc_v4_u64s_noerror(const struct bch_alloc_v4 *a)
 {
-       unsigned ret = (BCH_ALLOC_V4_BACKPOINTERS_START(a) ?:
+       return (BCH_ALLOC_V4_BACKPOINTERS_START(a) ?:
                        BCH_ALLOC_V4_U64s_V0) +
                BCH_ALLOC_V4_NR_BACKPOINTERS(a) *
                (sizeof(struct bch_backpointer) / sizeof(u64));
+}
 
+static inline unsigned alloc_v4_u64s(const struct bch_alloc_v4 *a)
+{
+       unsigned ret = alloc_v4_u64s_noerror(a);
        BUG_ON(ret > U8_MAX - BKEY_U64s);
        return ret;
 }
index a200442010025a0d8ee7b421d12edb32ff5c5a01..af7a71de1bdfeb8ab0c5dfae05fdf2b55a2c06d5 100644 (file)
@@ -54,7 +54,7 @@ int bch2_backpointer_invalid(struct bch_fs *c, struct bkey_s_c k,
        int ret = 0;
 
        bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size ||
-                        !bpos_eq(bp.k->p, bucket_pos_to_bp(c, bucket, bp.v->bucket_offset)),
+                        !bpos_eq(bp.k->p, bucket_pos_to_bp_noerror(ca, bucket, bp.v->bucket_offset)),
                         c, err,
                         backpointer_bucket_offset_wrong,
                         "backpointer bucket_offset wrong");
index 85949b9fd880ce2fcce508ba4018350a5dfac9ca..c1b274eadda141a755831aa4b2199f315cea95d9 100644 (file)
@@ -45,6 +45,15 @@ static inline struct bpos bp_pos_to_bucket(const struct bch_fs *c,
        return POS(bp_pos.inode, sector_to_bucket(ca, bucket_sector));
 }
 
+static inline struct bpos bucket_pos_to_bp_noerror(const struct bch_dev *ca,
+                                                  struct bpos bucket,
+                                                  u64 bucket_offset)
+{
+       return POS(bucket.inode,
+                  (bucket_to_sector(ca, bucket.offset) <<
+                   MAX_EXTENT_COMPRESS_RATIO_SHIFT) + bucket_offset);
+}
+
 /*
  * Convert from pos in alloc btree + bucket offset to pos in backpointer btree:
  */
@@ -53,10 +62,7 @@ static inline struct bpos bucket_pos_to_bp(const struct bch_fs *c,
                                           u64 bucket_offset)
 {
        struct bch_dev *ca = bch_dev_bkey_exists(c, bucket.inode);
-       struct bpos ret = POS(bucket.inode,
-                             (bucket_to_sector(ca, bucket.offset) <<
-                              MAX_EXTENT_COMPRESS_RATIO_SHIFT) + bucket_offset);
-
+       struct bpos ret = bucket_pos_to_bp_noerror(ca, bucket, bucket_offset);
        EBUG_ON(!bkey_eq(bucket, bp_pos_to_bucket(c, ret)));
        return ret;
 }
index f7fbfccd2b1e4d7e6bafabd839a6917de906edf9..2e8b1a489c2092be316aa08217477a9f3389337e 100644 (file)
@@ -591,6 +591,12 @@ struct bch_member {
        __le64                  btree_allocated_bitmap;
 };
 
+/*
+ * This limit comes from the bucket_gens array - it's a single allocation, and
+ * kernel allocation are limited to INT_MAX
+ */
+#define BCH_MEMBER_NBUCKETS_MAX        (INT_MAX - 64)
+
 #define BCH_MEMBER_V1_BYTES    56
 
 LE64_BITMASK(BCH_MEMBER_STATE,         struct bch_member, flags,  0,  4)
@@ -897,6 +903,8 @@ unsigned bcachefs_metadata_required_upgrade_below = bcachefs_metadata_version_re
 #define BCH_SB_SECTOR                  8
 #define BCH_SB_MEMBERS_MAX             64 /* XXX kill */
 
+#define BCH_SB_LAYOUT_SIZE_BITS_MAX    16 /* 32 MB */
+
 struct bch_sb_layout {
        __uuid_t                magic;  /* bcachefs superblock UUID */
        __u8                    layout_type;
index db336a43fc083a79615e81ce9da37ff4877005f9..a275a9e8e341aa0669073625d6b39d376139739a 100644 (file)
@@ -171,8 +171,8 @@ int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
        if (type >= BKEY_TYPE_NR)
                return 0;
 
-       bkey_fsck_err_on((type == BKEY_TYPE_btree ||
-                         (flags & BKEY_INVALID_COMMIT)) &&
+       bkey_fsck_err_on(k.k->type < KEY_TYPE_MAX &&
+                        (type == BKEY_TYPE_btree || (flags & BKEY_INVALID_COMMIT)) &&
                         !(bch2_key_types_allowed[type] & BIT_ULL(k.k->type)), c, err,
                         bkey_invalid_type_for_btree,
                         "invalid key type for btree %s (%s)",
index e8c1c530cd95f5bb1c34cb39f848cd842b0a88c6..7dafa1accec220bb49e267b5fed7360b747bf159 100644 (file)
@@ -956,13 +956,15 @@ void bch2_fs_btree_key_cache_exit(struct btree_key_cache *bc)
        }
 
 #ifdef __KERNEL__
-       for_each_possible_cpu(cpu) {
-               struct btree_key_cache_freelist *f =
-                       per_cpu_ptr(bc->pcpu_freed, cpu);
-
-               for (i = 0; i < f->nr; i++) {
-                       ck = f->objs[i];
-                       list_add(&ck->list, &items);
+       if (bc->pcpu_freed) {
+               for_each_possible_cpu(cpu) {
+                       struct btree_key_cache_freelist *f =
+                               per_cpu_ptr(bc->pcpu_freed, cpu);
+
+                       for (i = 0; i < f->nr; i++) {
+                               ck = f->objs[i];
+                               list_add(&ck->list, &items);
+                       }
                }
        }
 #endif
index c60794264da2898b4d8d64eb2cf6f94ac90afb1b..45cb8149d374c2878e8c607282ca4e5e7875f063 100644 (file)
@@ -57,13 +57,14 @@ static void found_btree_node_to_key(struct bkey_i *k, const struct found_btree_n
        bp->v.seq               = cpu_to_le64(f->cookie);
        bp->v.sectors_written   = 0;
        bp->v.flags             = 0;
+       bp->v.sectors_written   = cpu_to_le16(f->sectors_written);
        bp->v.min_key           = f->min_key;
        SET_BTREE_PTR_RANGE_UPDATED(&bp->v, f->range_updated);
        memcpy(bp->v.start, f->ptrs, sizeof(struct bch_extent_ptr) * f->nr_ptrs);
 }
 
 static bool found_btree_node_is_readable(struct btree_trans *trans,
-                                        const struct found_btree_node *f)
+                                        struct found_btree_node *f)
 {
        struct { __BKEY_PADDED(k, BKEY_BTREE_PTR_VAL_U64s_MAX); } k;
 
@@ -71,8 +72,10 @@ static bool found_btree_node_is_readable(struct btree_trans *trans,
 
        struct btree *b = bch2_btree_node_get_noiter(trans, &k.k, f->btree_id, f->level, false);
        bool ret = !IS_ERR_OR_NULL(b);
-       if (ret)
+       if (ret) {
+               f->sectors_written = b->written;
                six_unlock_read(&b->c.lock);
+       }
 
        /*
         * We might update this node's range; if that happens, we need the node
index abb7b27d556a9ff0f09e797494437a513122d8d3..5cfaeb5ac831b6396399d71858d2934e7d63c544 100644 (file)
@@ -9,6 +9,7 @@ struct found_btree_node {
        bool                    overwritten:1;
        u8                      btree_id;
        u8                      level;
+       unsigned                sectors_written;
        u32                     seq;
        u64                     cookie;
 
index 941401a210f56993359548e51b5095d0db45e691..82f179258867b7b1b6e5f21905f0bc3d3eaee41c 100644 (file)
@@ -525,7 +525,6 @@ int bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
                        "different types of data in same bucket: %s, %s",
                        bch2_data_type_str(g->data_type),
                        bch2_data_type_str(data_type))) {
-               BUG();
                ret = -EIO;
                goto err;
        }
@@ -629,7 +628,6 @@ int bch2_check_bucket_ref(struct btree_trans *trans,
                        bch2_data_type_str(ptr_data_type),
                        (printbuf_reset(&buf),
                         bch2_bkey_val_to_text(&buf, c, k), buf.buf));
-               BUG();
                ret = -EIO;
                goto err;
        }
index 7ed779b411f61e4e3f05a703ce9e091474237939..088fd2e7bdf12636bd999ff4b603e0cdf5702d31 100644 (file)
@@ -102,6 +102,7 @@ static inline int do_encrypt_sg(struct crypto_sync_skcipher *tfm,
        int ret;
 
        skcipher_request_set_sync_tfm(req, tfm);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
        skcipher_request_set_crypt(req, sg, sg, len, nonce.d);
 
        ret = crypto_skcipher_encrypt(req);
index 01a79fa3eacb211cb7cd779616f512d427102fd4..dbe35b80bc0b893cb2c914c699c14573966590e4 100644 (file)
        x(EINVAL,                       block_size_too_small)                   \
        x(EINVAL,                       bucket_size_too_small)                  \
        x(EINVAL,                       device_size_too_small)                  \
+       x(EINVAL,                       device_size_too_big)                    \
        x(EINVAL,                       device_not_a_member_of_filesystem)      \
        x(EINVAL,                       device_has_been_removed)                \
        x(EINVAL,                       device_splitbrain)                      \
index fce690007edfce089f054d81cc862c04c132c2b3..65b04b3c2679fe2cb12180f8cb9828ae0be9d0ab 100644 (file)
@@ -844,6 +844,9 @@ static int bch2_getattr(struct mnt_idmap *idmap,
        stat->blksize   = block_bytes(c);
        stat->blocks    = inode->v.i_blocks;
 
+       stat->subvol    = inode->ei_subvol;
+       stat->result_mask |= STATX_SUBVOL;
+
        if (request_mask & STATX_BTIME) {
                stat->result_mask |= STATX_BTIME;
                stat->btime = bch2_time_to_timespec(c, inode->ei_inode.bi_otime);
@@ -964,7 +967,6 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
        struct btree_iter iter;
        struct bkey_s_c k;
        struct bkey_buf cur, prev;
-       struct bpos end = POS(ei->v.i_ino, (start + len) >> 9);
        unsigned offset_into_extent, sectors;
        bool have_extent = false;
        u32 snapshot;
@@ -974,6 +976,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
        if (ret)
                return ret;
 
+       struct bpos end = POS(ei->v.i_ino, (start + len) >> 9);
        if (start + len < start)
                return -EINVAL;
 
index ca4a066e9a5428aa68f88d77f59e9c365a580d6c..0f95d7fb5ec0bddf755299a70908a3520c307f69 100644 (file)
@@ -606,7 +606,7 @@ int bch2_trigger_inode(struct btree_trans *trans,
                       struct bkey_s new,
                       unsigned flags)
 {
-       s64 nr = bkey_is_inode(new.k) - bkey_is_inode(old.k);
+       s64 nr = (s64) bkey_is_inode(new.k) - (s64) bkey_is_inode(old.k);
 
        if (flags & BTREE_TRIGGER_TRANSACTIONAL) {
                if (nr) {
index f137252bccc575b42a012a7876f8c81ddee28a21..40d7df7607dfd1a3b51be283c7791ec7f70d93a6 100644 (file)
@@ -199,9 +199,6 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
                                                    u64 new_i_size,
                                                    s64 i_sectors_delta)
 {
-       struct btree_iter iter;
-       struct bkey_i *k;
-       struct bkey_i_inode_v3 *inode;
        /*
         * Crazy performance optimization:
         * Every extent update needs to also update the inode: the inode trigger
@@ -214,25 +211,36 @@ static inline int bch2_extent_update_i_size_sectors(struct btree_trans *trans,
         * lost, but that's fine.
         */
        unsigned inode_update_flags = BTREE_UPDATE_NOJOURNAL;
-       int ret;
 
-       k = bch2_bkey_get_mut_noupdate(trans, &iter, BTREE_ID_inodes,
+       struct btree_iter iter;
+       struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_inodes,
                              SPOS(0,
                                   extent_iter->pos.inode,
                                   extent_iter->snapshot),
                              BTREE_ITER_CACHED);
-       ret = PTR_ERR_OR_ZERO(k);
+       int ret = bkey_err(k);
        if (unlikely(ret))
                return ret;
 
-       if (unlikely(k->k.type != KEY_TYPE_inode_v3)) {
-               k = bch2_inode_to_v3(trans, k);
-               ret = PTR_ERR_OR_ZERO(k);
+       /*
+        * varint_decode_fast(), in the inode .invalid method, reads up to 7
+        * bytes past the end of the buffer:
+        */
+       struct bkey_i *k_mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k) + 8);
+       ret = PTR_ERR_OR_ZERO(k_mut);
+       if (unlikely(ret))
+               goto err;
+
+       bkey_reassemble(k_mut, k);
+
+       if (unlikely(k_mut->k.type != KEY_TYPE_inode_v3)) {
+               k_mut = bch2_inode_to_v3(trans, k_mut);
+               ret = PTR_ERR_OR_ZERO(k_mut);
                if (unlikely(ret))
                        goto err;
        }
 
-       inode = bkey_i_to_inode_v3(k);
+       struct bkey_i_inode_v3 *inode = bkey_i_to_inode_v3(k_mut);
 
        if (!(le64_to_cpu(inode->v.bi_flags) & BCH_INODE_i_size_dirty) &&
            new_i_size > le64_to_cpu(inode->v.bi_size)) {
@@ -1505,6 +1513,8 @@ static void bch2_write_data_inline(struct bch_write_op *op, unsigned data_len)
        unsigned sectors;
        int ret;
 
+       memset(&op->failed, 0, sizeof(op->failed));
+
        op->flags |= BCH_WRITE_WROTE_DATA_INLINE;
        op->flags |= BCH_WRITE_DONE;
 
index 9c9a25dbd6137a6d51205c80cbf8d931fda918ef..a8b08e76d0d01e036cb34eef68c133e9930b1f97 100644 (file)
@@ -706,6 +706,12 @@ recheck_need_open:
 
                spin_unlock(&j->lock);
 
+               /*
+                * We're called from bch2_journal_flush_seq() -> wait_event();
+                * but this might block. We won't usually block, so we won't
+                * livelock:
+                */
+               sched_annotate_sleep();
                ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
                if (ret)
                        return ret;
@@ -870,6 +876,8 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou
 {
        struct journal_buf *ret = NULL;
 
+       /* We're inside wait_event(), but using mutex_lock(: */
+       sched_annotate_sleep();
        mutex_lock(&j->buf_lock);
        spin_lock(&j->lock);
        max_seq = min(max_seq, journal_cur_seq(j));
index bf68ea49447b95055a4f6a1e6e7c6a7e373aebc5..4d94b7742dbbae3b8dc251d24262c6ee9361aa4a 100644 (file)
@@ -968,24 +968,30 @@ static bool migrate_btree_pred(struct bch_fs *c, void *arg,
        return migrate_pred(c, arg, bkey_i_to_s_c(&b->key), io_opts, data_opts);
 }
 
+/*
+ * Ancient versions of bcachefs produced packed formats which could represent
+ * keys that the in memory format cannot represent; this checks for those
+ * formats so we can get rid of them.
+ */
 static bool bformat_needs_redo(struct bkey_format *f)
 {
-       unsigned i;
-
-       for (i = 0; i < f->nr_fields; i++) {
+       for (unsigned i = 0; i < f->nr_fields; i++) {
+               unsigned f_bits = f->bits_per_field[i];
                unsigned unpacked_bits = bch2_bkey_format_current.bits_per_field[i];
                u64 unpacked_mask = ~((~0ULL << 1) << (unpacked_bits - 1));
                u64 field_offset = le64_to_cpu(f->field_offset[i]);
 
-               if (f->bits_per_field[i] > unpacked_bits)
+               if (f_bits > unpacked_bits)
                        return true;
 
-               if ((f->bits_per_field[i] == unpacked_bits) && field_offset)
+               if ((f_bits == unpacked_bits) && field_offset)
                        return true;
 
-               if (((field_offset + ((1ULL << f->bits_per_field[i]) - 1)) &
-                    unpacked_mask) <
-                   field_offset)
+               u64 f_mask = f_bits
+                       ? ~((~0ULL << (f_bits - 1)) << 1)
+                       : 0;
+
+               if (((field_offset + f_mask) & unpacked_mask) < field_offset)
                        return true;
        }
 
index e68b34eab90a912a55727b1da0428b3655cb3834..556da07381069539e84d8c9ff91fec93b418c718 100644 (file)
@@ -560,13 +560,11 @@ static int bch2_fs_quota_read_inode(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct bch_inode_unpacked u;
        struct bch_snapshot_tree s_t;
-       int ret;
+       u32 tree = bch2_snapshot_tree(c, k.k->p.snapshot);
 
-       ret = bch2_snapshot_tree_lookup(trans,
-                       bch2_snapshot_tree(c, k.k->p.snapshot), &s_t);
+       int ret = bch2_snapshot_tree_lookup(trans, tree, &s_t);
        bch2_fs_inconsistent_on(bch2_err_matches(ret, ENOENT), c,
-                       "%s: snapshot tree %u not found", __func__,
-                       snapshot_t(c, k.k->p.snapshot)->tree);
+                       "%s: snapshot tree %u not found", __func__, tree);
        if (ret)
                return ret;
 
index be5b47619327001ac8191c026575f6ac18d74d16..8091d0686029f40a694042f860c91de8840576ed 100644 (file)
@@ -902,7 +902,8 @@ out:
                bch2_journal_keys_put_initial(c);
                bch2_find_btree_nodes_exit(&c->found_btree_nodes);
        }
-       kfree(clean);
+       if (!IS_ERR(clean))
+               kfree(clean);
 
        if (!ret &&
            test_bit(BCH_FS_need_delete_dead_snapshots, &c->flags) &&
index 35ca3f138de6fad2428f347c704c03992e2bc05a..194e55b11137b9133ed9cc9493362e1b148f017a 100644 (file)
@@ -278,6 +278,17 @@ static int bch2_sb_clean_validate(struct bch_sb *sb,
                return -BCH_ERR_invalid_sb_clean;
        }
 
+       for (struct jset_entry *entry = clean->start;
+            entry != vstruct_end(&clean->field);
+            entry = vstruct_next(entry)) {
+               if ((void *) vstruct_next(entry) > vstruct_end(&clean->field)) {
+                       prt_str(err, "entry type ");
+                       bch2_prt_jset_entry_type(err, le16_to_cpu(entry->type));
+                       prt_str(err, " overruns end of section");
+                       return -BCH_ERR_invalid_sb_clean;
+               }
+       }
+
        return 0;
 }
 
@@ -295,6 +306,9 @@ static void bch2_sb_clean_to_text(struct printbuf *out, struct bch_sb *sb,
        for (entry = clean->start;
             entry != vstruct_end(&clean->field);
             entry = vstruct_next(entry)) {
+               if ((void *) vstruct_next(entry) > vstruct_end(&clean->field))
+                       break;
+
                if (entry->type == BCH_JSET_ENTRY_btree_keys &&
                    !entry->u64s)
                        continue;
index 5b8e621ac5eb5780bb0c2e241196737bc0076e2e..44b3f0cb7b49747d9bdbd8cf34f401187c61d841 100644 (file)
@@ -124,9 +124,9 @@ static int validate_member(struct printbuf *err,
                           struct bch_sb *sb,
                           int i)
 {
-       if (le64_to_cpu(m.nbuckets) > LONG_MAX) {
-               prt_printf(err, "device %u: too many buckets (got %llu, max %lu)",
-                          i, le64_to_cpu(m.nbuckets), LONG_MAX);
+       if (le64_to_cpu(m.nbuckets) > BCH_MEMBER_NBUCKETS_MAX) {
+               prt_printf(err, "device %u: too many buckets (got %llu, max %u)",
+                          i, le64_to_cpu(m.nbuckets), BCH_MEMBER_NBUCKETS_MAX);
                return -BCH_ERR_invalid_sb_members;
        }
 
index 5efa64eca5f85af5637faa12aa85b83fbcde6ad3..5bf27d30ca2969017c6d33edde8c99ce1a36cb7b 100644 (file)
@@ -107,10 +107,10 @@ static inline struct bch_dev *__bch2_next_dev(struct bch_fs *c, struct bch_dev *
 
 static inline struct bch_dev *bch2_get_next_dev(struct bch_fs *c, struct bch_dev *ca)
 {
+       rcu_read_lock();
        if (ca)
                percpu_ref_put(&ca->ref);
 
-       rcu_read_lock();
        if ((ca = __bch2_next_dev(c, ca, NULL)))
                percpu_ref_get(&ca->ref);
        rcu_read_unlock();
@@ -132,10 +132,10 @@ static inline struct bch_dev *bch2_get_next_online_dev(struct bch_fs *c,
                                                       struct bch_dev *ca,
                                                       unsigned state_mask)
 {
+       rcu_read_lock();
        if (ca)
                percpu_ref_put(&ca->io_ref);
 
-       rcu_read_lock();
        while ((ca = __bch2_next_dev(c, ca, NULL)) &&
               (!((1 << ca->mi.state) & state_mask) ||
                !percpu_ref_tryget(&ca->io_ref)))
index 08ea3dbbbe97ce11833fe79baa5fd87935919339..bfdb15e7d778e24e6d6d327168646d18b17f4464 100644 (file)
@@ -232,7 +232,7 @@ struct bch_sb_field *bch2_sb_field_resize_id(struct bch_sb_handle *sb,
                        struct bch_sb_handle *dev_sb = &ca->disk_sb;
 
                        if (bch2_sb_realloc(dev_sb, le32_to_cpu(dev_sb->sb->u64s) + d)) {
-                               percpu_ref_put(&ca->ref);
+                               percpu_ref_put(&ca->io_ref);
                                return NULL;
                        }
                }
@@ -649,7 +649,7 @@ reread:
 
        bytes = vstruct_bytes(sb->sb);
 
-       if (bytes > 512 << sb->sb->layout.sb_max_size_bits) {
+       if (bytes > 512ULL << min(BCH_SB_LAYOUT_SIZE_BITS_MAX, sb->sb->layout.sb_max_size_bits)) {
                prt_printf(err, "Invalid superblock: too big (got %zu bytes, layout max %lu)",
                       bytes, 512UL << sb->sb->layout.sb_max_size_bits);
                return -BCH_ERR_invalid_sb_too_big;
@@ -923,6 +923,7 @@ int bch2_write_super(struct bch_fs *c)
        struct bch_devs_mask sb_written;
        bool wrote, can_mount_without_written, can_mount_with_written;
        unsigned degraded_flags = BCH_FORCE_IF_DEGRADED;
+       DARRAY(struct bch_dev *) online_devices = {};
        int ret = 0;
 
        trace_and_count(c, write_super, c, _RET_IP_);
@@ -935,6 +936,15 @@ int bch2_write_super(struct bch_fs *c)
        closure_init_stack(cl);
        memset(&sb_written, 0, sizeof(sb_written));
 
+       for_each_online_member(c, ca) {
+               ret = darray_push(&online_devices, ca);
+               if (bch2_fs_fatal_err_on(ret, c, "%s: error allocating online devices", __func__)) {
+                       percpu_ref_put(&ca->io_ref);
+                       goto out;
+               }
+               percpu_ref_get(&ca->io_ref);
+       }
+
        /* Make sure we're using the new magic numbers: */
        c->disk_sb.sb->magic = BCHFS_MAGIC;
        c->disk_sb.sb->layout.magic = BCHFS_MAGIC;
@@ -942,8 +952,8 @@ int bch2_write_super(struct bch_fs *c)
        le64_add_cpu(&c->disk_sb.sb->seq, 1);
 
        struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
-       for_each_online_member(c, ca)
-               __bch2_members_v2_get_mut(mi, ca->dev_idx)->seq = c->disk_sb.sb->seq;
+       darray_for_each(online_devices, ca)
+               __bch2_members_v2_get_mut(mi, (*ca)->dev_idx)->seq = c->disk_sb.sb->seq;
        c->disk_sb.sb->write_time = cpu_to_le64(ktime_get_real_seconds());
 
        if (test_bit(BCH_FS_error, &c->flags))
@@ -959,16 +969,15 @@ int bch2_write_super(struct bch_fs *c)
        bch2_sb_errors_from_cpu(c);
        bch2_sb_downgrade_update(c);
 
-       for_each_online_member(c, ca)
-               bch2_sb_from_fs(c, ca);
+       darray_for_each(online_devices, ca)
+               bch2_sb_from_fs(c, (*ca));
 
-       for_each_online_member(c, ca) {
+       darray_for_each(online_devices, ca) {
                printbuf_reset(&err);
 
-               ret = bch2_sb_validate(&ca->disk_sb, &err, WRITE);
+               ret = bch2_sb_validate(&(*ca)->disk_sb, &err, WRITE);
                if (ret) {
                        bch2_fs_inconsistent(c, "sb invalid before write: %s", err.buf);
-                       percpu_ref_put(&ca->io_ref);
                        goto out;
                }
        }
@@ -995,16 +1004,18 @@ int bch2_write_super(struct bch_fs *c)
                return -BCH_ERR_sb_not_downgraded;
        }
 
-       for_each_online_member(c, ca) {
-               __set_bit(ca->dev_idx, sb_written.d);
-               ca->sb_write_error = 0;
+       darray_for_each(online_devices, ca) {
+               __set_bit((*ca)->dev_idx, sb_written.d);
+               (*ca)->sb_write_error = 0;
        }
 
-       for_each_online_member(c, ca)
-               read_back_super(c, ca);
+       darray_for_each(online_devices, ca)
+               read_back_super(c, *ca);
        closure_sync(cl);
 
-       for_each_online_member(c, ca) {
+       darray_for_each(online_devices, cap) {
+               struct bch_dev *ca = *cap;
+
                if (ca->sb_write_error)
                        continue;
 
@@ -1031,17 +1042,20 @@ int bch2_write_super(struct bch_fs *c)
 
        do {
                wrote = false;
-               for_each_online_member(c, ca)
+               darray_for_each(online_devices, cap) {
+                       struct bch_dev *ca = *cap;
                        if (!ca->sb_write_error &&
                            sb < ca->disk_sb.sb->layout.nr_superblocks) {
                                write_one_super(c, ca, sb);
                                wrote = true;
                        }
+               }
                closure_sync(cl);
                sb++;
        } while (wrote);
 
-       for_each_online_member(c, ca) {
+       darray_for_each(online_devices, cap) {
+               struct bch_dev *ca = *cap;
                if (ca->sb_write_error)
                        __clear_bit(ca->dev_idx, sb_written.d);
                else
@@ -1077,6 +1091,9 @@ int bch2_write_super(struct bch_fs *c)
 out:
        /* Make new options visible after they're persistent: */
        bch2_sb_update(c);
+       darray_for_each(online_devices, ca)
+               percpu_ref_put(&(*ca)->io_ref);
+       darray_exit(&online_devices);
        printbuf_exit(&err);
        return ret;
 }
index 88e214c609bb2b6beab65b604acf1053596f3a8a..dddf57ec4511f3562592bce4c5c59988c9eed352 100644 (file)
@@ -1959,6 +1959,13 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
                goto err;
        }
 
+       if (nbuckets > BCH_MEMBER_NBUCKETS_MAX) {
+               bch_err(ca, "New device size too big (%llu greater than max %u)",
+                       nbuckets, BCH_MEMBER_NBUCKETS_MAX);
+               ret = -BCH_ERR_device_size_too_big;
+               goto err;
+       }
+
        if (bch2_dev_is_online(ca) &&
            get_capacity(ca->disk_sb.bdev->bd_disk) <
            ca->mi.bucket_size * nbuckets) {
@@ -2004,13 +2011,9 @@ err:
 /* return with ref on ca->ref: */
 struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *name)
 {
-       rcu_read_lock();
-       for_each_member_device_rcu(c, ca, NULL)
-               if (!strcmp(name, ca->name)) {
-                       rcu_read_unlock();
+       for_each_member_device(c, ca)
+               if (!strcmp(name, ca->name))
                        return ca;
-               }
-       rcu_read_unlock();
        return ERR_PTR(-BCH_ERR_ENOENT_dev_not_found);
 }
 
index f9d76072398da550e1ad4cd9c77bfcb3007c7c66..1640c46f215310a00f3925e7c05d3ffdcaafb424 100644 (file)
@@ -3719,8 +3719,7 @@ static int btrfs_file_open(struct inode *inode, struct file *filp)
 {
        int ret;
 
-       filp->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
-                       FMODE_CAN_ODIRECT;
+       filp->f_mode |= FMODE_NOWAIT | FMODE_CAN_ODIRECT;
 
        ret = fsverity_file_open(inode, filp);
        if (ret)
@@ -3850,6 +3849,7 @@ const struct file_operations btrfs_file_operations = {
        .compat_ioctl   = btrfs_compat_ioctl,
 #endif
        .remap_file_range = btrfs_remap_file_range,
+       .fop_flags      = FOP_BUFFER_RASYNC | FOP_BUFFER_WASYNC,
 };
 
 int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end)
index 7fed887e700c4e8e07b6ff7932434a384790b8da..f454ba34968350ec557a876f3e273be39b3ddc77 100644 (file)
@@ -8789,6 +8789,9 @@ static int btrfs_getattr(struct mnt_idmap *idmap,
        generic_fillattr(idmap, request_mask, inode, stat);
        stat->dev = BTRFS_I(inode)->root->anon_dev;
 
+       stat->subvol = BTRFS_I(inode)->root->root_key.objectid;
+       stat->result_mask |= STATX_SUBVOL;
+
        spin_lock(&BTRFS_I(inode)->lock);
        delalloc_bytes = BTRFS_I(inode)->new_delalloc_bytes;
        inode_bytes = inode_get_bytes(inode);
index 55f3ba6a831ca194e2d8405dbf7caa60fbd81dfc..0493272a7668ed0eb0104284e572503855645ca8 100644 (file)
@@ -3758,15 +3758,43 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg)
                goto drop_write;
        }
 
-       down_write(&fs_info->subvol_sem);
-
        switch (sa->cmd) {
        case BTRFS_QUOTA_CTL_ENABLE:
        case BTRFS_QUOTA_CTL_ENABLE_SIMPLE_QUOTA:
+               down_write(&fs_info->subvol_sem);
                ret = btrfs_quota_enable(fs_info, sa);
+               up_write(&fs_info->subvol_sem);
                break;
        case BTRFS_QUOTA_CTL_DISABLE:
+               /*
+                * Lock the cleaner mutex to prevent races with concurrent
+                * relocation, because relocation may be building backrefs for
+                * blocks of the quota root while we are deleting the root. This
+                * is like dropping fs roots of deleted snapshots/subvolumes, we
+                * need the same protection.
+                *
+                * This also prevents races between concurrent tasks trying to
+                * disable quotas, because we will unlock and relock
+                * qgroup_ioctl_lock across BTRFS_FS_QUOTA_ENABLED changes.
+                *
+                * We take this here because we have the dependency of
+                *
+                * inode_lock -> subvol_sem
+                *
+                * because of rename.  With relocation we can prealloc extents,
+                * so that makes the dependency chain
+                *
+                * cleaner_mutex -> inode_lock -> subvol_sem
+                *
+                * so we must take the cleaner_mutex here before we take the
+                * subvol_sem.  The deadlock can't actually happen, but this
+                * quiets lockdep.
+                */
+               mutex_lock(&fs_info->cleaner_mutex);
+               down_write(&fs_info->subvol_sem);
                ret = btrfs_quota_disable(fs_info);
+               up_write(&fs_info->subvol_sem);
+               mutex_unlock(&fs_info->cleaner_mutex);
                break;
        default:
                ret = -EINVAL;
@@ -3774,7 +3802,6 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg)
        }
 
        kfree(sa);
-       up_write(&fs_info->subvol_sem);
 drop_write:
        mnt_drop_write_file(file);
        return ret;
index b749ba45da2ba2b13d75695e882ab343dda9439c..c2a42bcde98e0ee4edc4ed171f44800cf53d7284 100644 (file)
@@ -1188,6 +1188,7 @@ struct btrfs_ordered_extent *btrfs_split_ordered_extent(
        ordered->disk_bytenr += len;
        ordered->num_bytes -= len;
        ordered->disk_num_bytes -= len;
+       ordered->ram_bytes -= len;
 
        if (test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags)) {
                ASSERT(ordered->bytes_left == 0);
index cf8820ce7aa2979920c6daafc1071c26571ecee6..40e5f7f2fcb7f852f22729fefa640895f57d9933 100644 (file)
@@ -1342,16 +1342,10 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        lockdep_assert_held_write(&fs_info->subvol_sem);
 
        /*
-        * Lock the cleaner mutex to prevent races with concurrent relocation,
-        * because relocation may be building backrefs for blocks of the quota
-        * root while we are deleting the root. This is like dropping fs roots
-        * of deleted snapshots/subvolumes, we need the same protection.
-        *
-        * This also prevents races between concurrent tasks trying to disable
-        * quotas, because we will unlock and relock qgroup_ioctl_lock across
-        * BTRFS_FS_QUOTA_ENABLED changes.
+        * Relocation will mess with backrefs, so make sure we have the
+        * cleaner_mutex held to protect us from relocate.
         */
-       mutex_lock(&fs_info->cleaner_mutex);
+       lockdep_assert_held(&fs_info->cleaner_mutex);
 
        mutex_lock(&fs_info->qgroup_ioctl_lock);
        if (!fs_info->quota_root)
@@ -1373,9 +1367,13 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
        clear_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
        btrfs_qgroup_wait_for_completion(fs_info, false);
 
+       /*
+        * We have nothing held here and no trans handle, just return the error
+        * if there is one.
+        */
        ret = flush_reservations(fs_info);
        if (ret)
-               goto out_unlock_cleaner;
+               return ret;
 
        /*
         * 1 For the root item
@@ -1439,9 +1437,6 @@ out:
                btrfs_end_transaction(trans);
        else if (trans)
                ret = btrfs_commit_transaction(trans);
-out_unlock_cleaner:
-       mutex_unlock(&fs_info->cleaner_mutex);
-
        return ret;
 }
 
@@ -3050,6 +3045,8 @@ int btrfs_qgroup_check_inherit(struct btrfs_fs_info *fs_info,
                               struct btrfs_qgroup_inherit *inherit,
                               size_t size)
 {
+       if (!btrfs_qgroup_enabled(fs_info))
+               return 0;
        if (inherit->flags & ~BTRFS_QGROUP_INHERIT_FLAGS_SUPP)
                return -EOPNOTSUPP;
        if (size < sizeof(*inherit) || size > PAGE_SIZE)
index c8fbcae4e88ea57e76729855392d95a448b0e92c..32604e9b31c3ee99a97b3ed7bfc4486225e3c213 100644 (file)
@@ -1797,6 +1797,11 @@ enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf)
                return BTRFS_TREE_BLOCK_INVALID_LEVEL;
        }
 
+       if (unlikely(!btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_WRITTEN))) {
+               generic_err(leaf, 0, "invalid flag for leaf, WRITTEN not set");
+               return BTRFS_TREE_BLOCK_WRITTEN_NOT_SET;
+       }
+
        /*
         * Extent buffers from a relocation tree have a owner field that
         * corresponds to the subvolume tree they are based on. So just from an
@@ -1858,6 +1863,7 @@ enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf)
        for (slot = 0; slot < nritems; slot++) {
                u32 item_end_expected;
                u64 item_data_end;
+               enum btrfs_tree_block_status ret;
 
                btrfs_item_key_to_cpu(leaf, &key, slot);
 
@@ -1913,21 +1919,10 @@ enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf)
                        return BTRFS_TREE_BLOCK_INVALID_OFFSETS;
                }
 
-               /*
-                * We only want to do this if WRITTEN is set, otherwise the leaf
-                * may be in some intermediate state and won't appear valid.
-                */
-               if (btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_WRITTEN)) {
-                       enum btrfs_tree_block_status ret;
-
-                       /*
-                        * Check if the item size and content meet other
-                        * criteria
-                        */
-                       ret = check_leaf_item(leaf, &key, slot, &prev_key);
-                       if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
-                               return ret;
-               }
+               /* Check if the item size and content meet other criteria. */
+               ret = check_leaf_item(leaf, &key, slot, &prev_key);
+               if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
+                       return ret;
 
                prev_key.objectid = key.objectid;
                prev_key.type = key.type;
@@ -1957,6 +1952,11 @@ enum btrfs_tree_block_status __btrfs_check_node(struct extent_buffer *node)
        int level = btrfs_header_level(node);
        u64 bytenr;
 
+       if (unlikely(!btrfs_header_flag(node, BTRFS_HEADER_FLAG_WRITTEN))) {
+               generic_err(node, 0, "invalid flag for node, WRITTEN not set");
+               return BTRFS_TREE_BLOCK_WRITTEN_NOT_SET;
+       }
+
        if (unlikely(level <= 0 || level >= BTRFS_MAX_LEVEL)) {
                generic_err(node, 0,
                        "invalid level for node, have %d expect [1, %d]",
index 5c809b50b2d09bbcbbae911774233182658c0d66..01669cfa6578de5fde772118634e13039ad76d78 100644 (file)
@@ -53,6 +53,7 @@ enum btrfs_tree_block_status {
        BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
        BTRFS_TREE_BLOCK_INVALID_ITEM,
        BTRFS_TREE_BLOCK_INVALID_OWNER,
+       BTRFS_TREE_BLOCK_WRITTEN_NOT_SET,
 };
 
 /*
index f15591f3e54fa4cd7e92103e17b0ae74eb1a54f9..ef6bd2f4251b523ecfa4e0c31fc3c7eb0d26d332 100644 (file)
@@ -3455,6 +3455,7 @@ again:
                         * alignment and size).
                         */
                        ret = -EUCLEAN;
+                       mutex_unlock(&fs_info->reclaim_bgs_lock);
                        goto error;
                }
 
index 1d685357e67fc71ffc2be73513b00f7efd8ee906..e667dbcd20e8ca7339c7dde53270fe00f62a7ee2 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/file.h>
 #include <linux/uio.h>
+#include <linux/bio.h>
 #include <linux/falloc.h>
 #include <linux/sched/mm.h>
 #include <trace/events/fscache.h>
@@ -493,7 +494,7 @@ out_no_object:
  * boundary as appropriate.
  */
 static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,
-                                                   loff_t i_size)
+                                                   unsigned long long i_size)
 {
        return cachefiles_do_prepare_read(&subreq->rreq->cache_resources,
                                          subreq->start, &subreq->len, i_size,
@@ -622,6 +623,77 @@ static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
        return ret;
 }
 
+static void cachefiles_prepare_write_subreq(struct netfs_io_subrequest *subreq)
+{
+       struct netfs_io_request *wreq = subreq->rreq;
+       struct netfs_cache_resources *cres = &wreq->cache_resources;
+
+       _enter("W=%x[%x] %llx", wreq->debug_id, subreq->debug_index, subreq->start);
+
+       subreq->max_len = ULONG_MAX;
+       subreq->max_nr_segs = BIO_MAX_VECS;
+
+       if (!cachefiles_cres_file(cres)) {
+               if (!fscache_wait_for_operation(cres, FSCACHE_WANT_WRITE))
+                       return netfs_prepare_write_failed(subreq);
+               if (!cachefiles_cres_file(cres))
+                       return netfs_prepare_write_failed(subreq);
+       }
+}
+
+static void cachefiles_issue_write(struct netfs_io_subrequest *subreq)
+{
+       struct netfs_io_request *wreq = subreq->rreq;
+       struct netfs_cache_resources *cres = &wreq->cache_resources;
+       struct cachefiles_object *object = cachefiles_cres_object(cres);
+       struct cachefiles_cache *cache = object->volume->cache;
+       const struct cred *saved_cred;
+       size_t off, pre, post, len = subreq->len;
+       loff_t start = subreq->start;
+       int ret;
+
+       _enter("W=%x[%x] %llx-%llx",
+              wreq->debug_id, subreq->debug_index, start, start + len - 1);
+
+       /* We need to start on the cache granularity boundary */
+       off = start & (CACHEFILES_DIO_BLOCK_SIZE - 1);
+       if (off) {
+               pre = CACHEFILES_DIO_BLOCK_SIZE - off;
+               if (pre >= len) {
+                       netfs_write_subrequest_terminated(subreq, len, false);
+                       return;
+               }
+               subreq->transferred += pre;
+               start += pre;
+               len -= pre;
+               iov_iter_advance(&subreq->io_iter, pre);
+       }
+
+       /* We also need to end on the cache granularity boundary */
+       post = len & (CACHEFILES_DIO_BLOCK_SIZE - 1);
+       if (post) {
+               len -= post;
+               if (len == 0) {
+                       netfs_write_subrequest_terminated(subreq, post, false);
+                       return;
+               }
+               iov_iter_truncate(&subreq->io_iter, len);
+       }
+
+       cachefiles_begin_secure(cache, &saved_cred);
+       ret = __cachefiles_prepare_write(object, cachefiles_cres_file(cres),
+                                        &start, &len, len, true);
+       cachefiles_end_secure(cache, saved_cred);
+       if (ret < 0) {
+               netfs_write_subrequest_terminated(subreq, ret, false);
+               return;
+       }
+
+       cachefiles_write(&subreq->rreq->cache_resources,
+                        subreq->start, &subreq->io_iter,
+                        netfs_write_subrequest_terminated, subreq);
+}
+
 /*
  * Clean up an operation.
  */
@@ -638,8 +710,10 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
        .end_operation          = cachefiles_end_operation,
        .read                   = cachefiles_read,
        .write                  = cachefiles_write,
+       .issue_write            = cachefiles_issue_write,
        .prepare_read           = cachefiles_prepare_read,
        .prepare_write          = cachefiles_prepare_write,
+       .prepare_write_subreq   = cachefiles_prepare_write_subreq,
        .prepare_ondemand_read  = cachefiles_prepare_ondemand_read,
        .query_occupancy        = cachefiles_query_occupancy,
 };
index ee9caf7916fb95931e08e41467cc97ddba950c0b..8c16bc5250ef56cb8d0864d3b4b054466d57f250 100644 (file)
@@ -193,7 +193,7 @@ static void ceph_netfs_expand_readahead(struct netfs_io_request *rreq)
         * block, but do not exceed the file size, unless the original
         * request already exceeds it.
         */
-       new_end = min(round_up(end, lo->stripe_unit), rreq->i_size);
+       new_end = umin(round_up(end, lo->stripe_unit), rreq->i_size);
        if (new_end > end && new_end <= rreq->start + max_len)
                rreq->len = new_end - rreq->start;
 
@@ -498,11 +498,6 @@ const struct netfs_request_ops ceph_netfs_ops = {
 };
 
 #ifdef CONFIG_CEPH_FSCACHE
-static void ceph_set_page_fscache(struct page *page)
-{
-       set_page_fscache(page);
-}
-
 static void ceph_fscache_write_terminated(void *priv, ssize_t error, bool was_async)
 {
        struct inode *inode = priv;
@@ -517,13 +512,9 @@ static void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, b
        struct fscache_cookie *cookie = ceph_fscache_cookie(ci);
 
        fscache_write_to_cache(cookie, inode->i_mapping, off, len, i_size_read(inode),
-                              ceph_fscache_write_terminated, inode, caching);
+                              ceph_fscache_write_terminated, inode, true, caching);
 }
 #else
-static inline void ceph_set_page_fscache(struct page *page)
-{
-}
-
 static inline void ceph_fscache_write_to_cache(struct inode *inode, u64 off, u64 len, bool caching)
 {
 }
@@ -715,8 +706,6 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
                len = wlen;
 
        set_page_writeback(page);
-       if (caching)
-               ceph_set_page_fscache(page);
        ceph_fscache_write_to_cache(inode, page_off, len, caching);
 
        if (IS_ENCRYPTED(inode)) {
@@ -800,8 +789,6 @@ static int ceph_writepage(struct page *page, struct writeback_control *wbc)
                return AOP_WRITEPAGE_ACTIVATE;
        }
 
-       wait_on_page_fscache(page);
-
        err = writepage_nounlock(page, wbc);
        if (err == -ERESTARTSYS) {
                /* direct memory reclaimer was killed by SIGKILL. return 0
@@ -1075,7 +1062,7 @@ get_more_pages:
                                unlock_page(page);
                                break;
                        }
-                       if (PageWriteback(page) || PageFsCache(page)) {
+                       if (PageWriteback(page)) {
                                if (wbc->sync_mode == WB_SYNC_NONE) {
                                        doutc(cl, "%p under writeback\n", page);
                                        unlock_page(page);
@@ -1083,7 +1070,6 @@ get_more_pages:
                                }
                                doutc(cl, "waiting on writeback %p\n", page);
                                wait_on_page_writeback(page);
-                               wait_on_page_fscache(page);
                        }
 
                        if (!clear_page_dirty_for_io(page)) {
@@ -1268,8 +1254,6 @@ new_request:
                        }
 
                        set_page_writeback(page);
-                       if (caching)
-                               ceph_set_page_fscache(page);
                        len += thp_size(page);
                }
                ceph_fscache_write_to_cache(inode, offset, len, caching);
@@ -1513,7 +1497,7 @@ static int ceph_write_begin(struct file *file, struct address_space *mapping,
        if (r < 0)
                return r;
 
-       folio_wait_fscache(folio);
+       folio_wait_private_2(folio); /* [DEPRECATED] */
        WARN_ON_ONCE(!folio_test_locked(folio));
        *pagep = &folio->page;
        return 0;
index 7b2e77517f235ecd47264061c04bae2e6d0b7c83..99561fddcb388b8f1743e7323085ec7dcd26f727 100644 (file)
@@ -577,6 +577,8 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
 
        /* Set parameters for the netfs library */
        netfs_inode_init(&ci->netfs, &ceph_netfs_ops, false);
+       /* [DEPRECATED] Use PG_private_2 to mark folio being written to the cache. */
+       __set_bit(NETFS_ICTX_USE_PGPRIV2, &ci->netfs.flags);
 
        spin_lock_init(&ci->i_ceph_lock);
 
index 71a8e943a0fa506c93fd7f11400de9a5d7e23e01..407095188f83a7faeec0a8c0542fb6598952b7be 100644 (file)
@@ -355,7 +355,7 @@ static inline void __d_clear_type_and_inode(struct dentry *dentry)
        flags &= ~DCACHE_ENTRY_TYPE;
        WRITE_ONCE(dentry->d_flags, flags);
        dentry->d_inode = NULL;
-       if (dentry->d_flags & DCACHE_LRU_LIST)
+       if (flags & DCACHE_LRU_LIST)
                this_cpu_inc(nr_dentry_negative);
 }
 
index a40da006543361c890aa5038a266e0300baaf4ec..dc51df0b118d0aa2f0853a54072457468a85132d 100644 (file)
@@ -14,7 +14,8 @@
 
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/mount.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/kobject.h>
@@ -23,7 +24,6 @@
 #include <linux/fsnotify.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
-#include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
 #include <linux/security.h>
@@ -77,7 +77,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb)
        return inode;
 }
 
-struct debugfs_mount_opts {
+struct debugfs_fs_info {
        kuid_t uid;
        kgid_t gid;
        umode_t mode;
@@ -89,68 +89,51 @@ enum {
        Opt_uid,
        Opt_gid,
        Opt_mode,
-       Opt_err
 };
 
-static const match_table_t tokens = {
-       {Opt_uid, "uid=%u"},
-       {Opt_gid, "gid=%u"},
-       {Opt_mode, "mode=%o"},
-       {Opt_err, NULL}
+static const struct fs_parameter_spec debugfs_param_specs[] = {
+       fsparam_u32     ("gid",         Opt_gid),
+       fsparam_u32oct  ("mode",        Opt_mode),
+       fsparam_u32     ("uid",         Opt_uid),
+       {}
 };
 
-struct debugfs_fs_info {
-       struct debugfs_mount_opts mount_opts;
-};
-
-static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
+static int debugfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
-       substring_t args[MAX_OPT_ARGS];
-       int option;
-       int token;
+       struct debugfs_fs_info *opts = fc->s_fs_info;
+       struct fs_parse_result result;
        kuid_t uid;
        kgid_t gid;
-       char *p;
-
-       opts->opts = 0;
-       opts->mode = DEBUGFS_DEFAULT_MODE;
-
-       while ((p = strsep(&data, ",")) != NULL) {
-               if (!*p)
-                       continue;
-
-               token = match_token(p, tokens, args);
-               switch (token) {
-               case Opt_uid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       uid = make_kuid(current_user_ns(), option);
-                       if (!uid_valid(uid))
-                               return -EINVAL;
-                       opts->uid = uid;
-                       break;
-               case Opt_gid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       gid = make_kgid(current_user_ns(), option);
-                       if (!gid_valid(gid))
-                               return -EINVAL;
-                       opts->gid = gid;
-                       break;
-               case Opt_mode:
-                       if (match_octal(&args[0], &option))
-                               return -EINVAL;
-                       opts->mode = option & S_IALLUGO;
-                       break;
-               /*
-                * We might like to report bad mount options here;
-                * but traditionally debugfs has ignored all mount options
-                */
-               }
-
-               opts->opts |= BIT(token);
+       int opt;
+
+       opt = fs_parse(fc, debugfs_param_specs, param, &result);
+       if (opt < 0)
+               return opt;
+
+       switch (opt) {
+       case Opt_uid:
+               uid = make_kuid(current_user_ns(), result.uint_32);
+               if (!uid_valid(uid))
+                       return invalf(fc, "Unknown uid");
+               opts->uid = uid;
+               break;
+       case Opt_gid:
+               gid = make_kgid(current_user_ns(), result.uint_32);
+               if (!gid_valid(gid))
+                       return invalf(fc, "Unknown gid");
+               opts->gid = gid;
+               break;
+       case Opt_mode:
+               opts->mode = result.uint_32 & S_IALLUGO;
+               break;
+       /*
+        * We might like to report bad mount options here;
+        * but traditionally debugfs has ignored all mount options
+        */
        }
 
+       opts->opts |= BIT(opt);
+
        return 0;
 }
 
@@ -158,23 +141,22 @@ static void _debugfs_apply_options(struct super_block *sb, bool remount)
 {
        struct debugfs_fs_info *fsi = sb->s_fs_info;
        struct inode *inode = d_inode(sb->s_root);
-       struct debugfs_mount_opts *opts = &fsi->mount_opts;
 
        /*
         * On remount, only reset mode/uid/gid if they were provided as mount
         * options.
         */
 
-       if (!remount || opts->opts & BIT(Opt_mode)) {
+       if (!remount || fsi->opts & BIT(Opt_mode)) {
                inode->i_mode &= ~S_IALLUGO;
-               inode->i_mode |= opts->mode;
+               inode->i_mode |= fsi->mode;
        }
 
-       if (!remount || opts->opts & BIT(Opt_uid))
-               inode->i_uid = opts->uid;
+       if (!remount || fsi->opts & BIT(Opt_uid))
+               inode->i_uid = fsi->uid;
 
-       if (!remount || opts->opts & BIT(Opt_gid))
-               inode->i_gid = opts->gid;
+       if (!remount || fsi->opts & BIT(Opt_gid))
+               inode->i_gid = fsi->gid;
 }
 
 static void debugfs_apply_options(struct super_block *sb)
@@ -187,35 +169,33 @@ static void debugfs_apply_options_remount(struct super_block *sb)
        _debugfs_apply_options(sb, true);
 }
 
-static int debugfs_remount(struct super_block *sb, int *flags, char *data)
+static int debugfs_reconfigure(struct fs_context *fc)
 {
-       int err;
-       struct debugfs_fs_info *fsi = sb->s_fs_info;
+       struct super_block *sb = fc->root->d_sb;
+       struct debugfs_fs_info *sb_opts = sb->s_fs_info;
+       struct debugfs_fs_info *new_opts = fc->s_fs_info;
 
        sync_filesystem(sb);
-       err = debugfs_parse_options(data, &fsi->mount_opts);
-       if (err)
-               goto fail;
 
+       /* structure copy of new mount options to sb */
+       *sb_opts = *new_opts;
        debugfs_apply_options_remount(sb);
 
-fail:
-       return err;
+       return 0;
 }
 
 static int debugfs_show_options(struct seq_file *m, struct dentry *root)
 {
        struct debugfs_fs_info *fsi = root->d_sb->s_fs_info;
-       struct debugfs_mount_opts *opts = &fsi->mount_opts;
 
-       if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
+       if (!uid_eq(fsi->uid, GLOBAL_ROOT_UID))
                seq_printf(m, ",uid=%u",
-                          from_kuid_munged(&init_user_ns, opts->uid));
-       if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
+                          from_kuid_munged(&init_user_ns, fsi->uid));
+       if (!gid_eq(fsi->gid, GLOBAL_ROOT_GID))
                seq_printf(m, ",gid=%u",
-                          from_kgid_munged(&init_user_ns, opts->gid));
-       if (opts->mode != DEBUGFS_DEFAULT_MODE)
-               seq_printf(m, ",mode=%o", opts->mode);
+                          from_kgid_munged(&init_user_ns, fsi->gid));
+       if (fsi->mode != DEBUGFS_DEFAULT_MODE)
+               seq_printf(m, ",mode=%o", fsi->mode);
 
        return 0;
 }
@@ -229,7 +209,6 @@ static void debugfs_free_inode(struct inode *inode)
 
 static const struct super_operations debugfs_super_operations = {
        .statfs         = simple_statfs,
-       .remount_fs     = debugfs_remount,
        .show_options   = debugfs_show_options,
        .free_inode     = debugfs_free_inode,
 };
@@ -263,26 +242,14 @@ static const struct dentry_operations debugfs_dops = {
        .d_automount = debugfs_automount,
 };
 
-static int debug_fill_super(struct super_block *sb, void *data, int silent)
+static int debugfs_fill_super(struct super_block *sb, struct fs_context *fc)
 {
        static const struct tree_descr debug_files[] = {{""}};
-       struct debugfs_fs_info *fsi;
        int err;
 
-       fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
-       sb->s_fs_info = fsi;
-       if (!fsi) {
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       err = debugfs_parse_options(data, &fsi->mount_opts);
+       err = simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
        if (err)
-               goto fail;
-
-       err  =  simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
-       if (err)
-               goto fail;
+               return err;
 
        sb->s_op = &debugfs_super_operations;
        sb->s_d_op = &debugfs_dops;
@@ -290,27 +257,48 @@ static int debug_fill_super(struct super_block *sb, void *data, int silent)
        debugfs_apply_options(sb);
 
        return 0;
-
-fail:
-       kfree(fsi);
-       sb->s_fs_info = NULL;
-       return err;
 }
 
-static struct dentry *debug_mount(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data)
+static int debugfs_get_tree(struct fs_context *fc)
 {
        if (!(debugfs_allow & DEBUGFS_ALLOW_API))
-               return ERR_PTR(-EPERM);
+               return -EPERM;
+
+       return get_tree_single(fc, debugfs_fill_super);
+}
+
+static void debugfs_free_fc(struct fs_context *fc)
+{
+       kfree(fc->s_fs_info);
+}
 
-       return mount_single(fs_type, flags, data, debug_fill_super);
+static const struct fs_context_operations debugfs_context_ops = {
+       .free           = debugfs_free_fc,
+       .parse_param    = debugfs_parse_param,
+       .get_tree       = debugfs_get_tree,
+       .reconfigure    = debugfs_reconfigure,
+};
+
+static int debugfs_init_fs_context(struct fs_context *fc)
+{
+       struct debugfs_fs_info *fsi;
+
+       fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
+       if (!fsi)
+               return -ENOMEM;
+
+       fsi->mode = DEBUGFS_DEFAULT_MODE;
+
+       fc->s_fs_info = fsi;
+       fc->ops = &debugfs_context_ops;
+       return 0;
 }
 
 static struct file_system_type debug_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "debugfs",
-       .mount =        debug_mount,
+       .init_fs_context = debugfs_init_fs_context,
+       .parameters =   debugfs_param_specs,
        .kill_sb =      kill_litter_super,
 };
 MODULE_ALIAS_FS("debugfs");
index 62c97ff9e852a15b495b1bdb3790290dddc33515..b0aafe640fa4286d3f2fb64a56578b8c4d53a8b1 100644 (file)
@@ -1217,7 +1217,6 @@ ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
         */
        inode_dio_begin(inode);
 
-       retval = 0;
        sdio.blkbits = blkbits;
        sdio.blkfactor = i_blkbits - blkbits;
        sdio.block_in_file = offset >> blkbits;
index 3fe41964c0d8d95a991e7de307bef6b4664d95b0..7f9f68c00ef63c76a3353ba354406cba6d4c0682 100644 (file)
@@ -300,9 +300,11 @@ write_tag_66_packet(char *signature, u8 cipher_code,
         *         | Key Identifier Size      | 1 or 2 bytes |
         *         | Key Identifier           | arbitrary    |
         *         | File Encryption Key Size | 1 or 2 bytes |
+        *         | Cipher Code              | 1 byte       |
         *         | File Encryption Key      | arbitrary    |
+        *         | Checksum                 | 2 bytes      |
         */
-       data_len = (5 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size);
+       data_len = (8 + ECRYPTFS_SIG_SIZE_HEX + crypt_stat->key_size);
        *packet = kmalloc(data_len, GFP_KERNEL);
        message = *packet;
        if (!message) {
index 8aff1a724805a67ad3733fbce2127a39e563e01d..62da538d91cbd47cea44f4d021096c6a3a654908 100644 (file)
@@ -151,7 +151,7 @@ static int erofs_fscache_read_io_async(struct fscache_cookie *cookie,
                if (WARN_ON(len == 0))
                        source = NETFS_INVALID_READ;
                if (source != NETFS_READ_FROM_CACHE) {
-                       erofs_err(NULL, "prepare_read failed (source %d)", source);
+                       erofs_err(NULL, "prepare_ondemand_read failed (source %d)", source);
                        return -EIO;
                }
 
index 39c67119f43bfd762aa204a1edcaa77916f5fb76..d28ccfc0352b1ae4728fb25fdf8672bd0ee81789 100644 (file)
@@ -84,13 +84,6 @@ struct erofs_dev_context {
        bool flatdev;
 };
 
-struct erofs_fs_context {
-       struct erofs_mount_opts opt;
-       struct erofs_dev_context *devs;
-       char *fsid;
-       char *domain_id;
-};
-
 /* all filesystem-wide lz4 configurations */
 struct erofs_sb_lz4_info {
        /* # of pages needed for EROFS lz4 rolling decompression */
index c0eb139adb07a8ce852edd56370a79e5760036d9..30b49b2eee53409a0b4b293a4ff579eceb2d5087 100644 (file)
@@ -370,18 +370,18 @@ out:
        return ret;
 }
 
-static void erofs_default_options(struct erofs_fs_context *ctx)
+static void erofs_default_options(struct erofs_sb_info *sbi)
 {
 #ifdef CONFIG_EROFS_FS_ZIP
-       ctx->opt.cache_strategy = EROFS_ZIP_CACHE_READAROUND;
-       ctx->opt.max_sync_decompress_pages = 3;
-       ctx->opt.sync_decompress = EROFS_SYNC_DECOMPRESS_AUTO;
+       sbi->opt.cache_strategy = EROFS_ZIP_CACHE_READAROUND;
+       sbi->opt.max_sync_decompress_pages = 3;
+       sbi->opt.sync_decompress = EROFS_SYNC_DECOMPRESS_AUTO;
 #endif
 #ifdef CONFIG_EROFS_FS_XATTR
-       set_opt(&ctx->opt, XATTR_USER);
+       set_opt(&sbi->opt, XATTR_USER);
 #endif
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
-       set_opt(&ctx->opt, POSIX_ACL);
+       set_opt(&sbi->opt, POSIX_ACL);
 #endif
 }
 
@@ -426,16 +426,16 @@ static const struct fs_parameter_spec erofs_fs_parameters[] = {
 static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
 {
 #ifdef CONFIG_FS_DAX
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *sbi = fc->s_fs_info;
 
        switch (mode) {
        case EROFS_MOUNT_DAX_ALWAYS:
-               set_opt(&ctx->opt, DAX_ALWAYS);
-               clear_opt(&ctx->opt, DAX_NEVER);
+               set_opt(&sbi->opt, DAX_ALWAYS);
+               clear_opt(&sbi->opt, DAX_NEVER);
                return true;
        case EROFS_MOUNT_DAX_NEVER:
-               set_opt(&ctx->opt, DAX_NEVER);
-               clear_opt(&ctx->opt, DAX_ALWAYS);
+               set_opt(&sbi->opt, DAX_NEVER);
+               clear_opt(&sbi->opt, DAX_ALWAYS);
                return true;
        default:
                DBG_BUGON(1);
@@ -450,7 +450,7 @@ static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode)
 static int erofs_fc_parse_param(struct fs_context *fc,
                                struct fs_parameter *param)
 {
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *sbi = fc->s_fs_info;
        struct fs_parse_result result;
        struct erofs_device_info *dif;
        int opt, ret;
@@ -463,9 +463,9 @@ static int erofs_fc_parse_param(struct fs_context *fc,
        case Opt_user_xattr:
 #ifdef CONFIG_EROFS_FS_XATTR
                if (result.boolean)
-                       set_opt(&ctx->opt, XATTR_USER);
+                       set_opt(&sbi->opt, XATTR_USER);
                else
-                       clear_opt(&ctx->opt, XATTR_USER);
+                       clear_opt(&sbi->opt, XATTR_USER);
 #else
                errorfc(fc, "{,no}user_xattr options not supported");
 #endif
@@ -473,16 +473,16 @@ static int erofs_fc_parse_param(struct fs_context *fc,
        case Opt_acl:
 #ifdef CONFIG_EROFS_FS_POSIX_ACL
                if (result.boolean)
-                       set_opt(&ctx->opt, POSIX_ACL);
+                       set_opt(&sbi->opt, POSIX_ACL);
                else
-                       clear_opt(&ctx->opt, POSIX_ACL);
+                       clear_opt(&sbi->opt, POSIX_ACL);
 #else
                errorfc(fc, "{,no}acl options not supported");
 #endif
                break;
        case Opt_cache_strategy:
 #ifdef CONFIG_EROFS_FS_ZIP
-               ctx->opt.cache_strategy = result.uint_32;
+               sbi->opt.cache_strategy = result.uint_32;
 #else
                errorfc(fc, "compression not supported, cache_strategy ignored");
 #endif
@@ -504,27 +504,27 @@ static int erofs_fc_parse_param(struct fs_context *fc,
                        kfree(dif);
                        return -ENOMEM;
                }
-               down_write(&ctx->devs->rwsem);
-               ret = idr_alloc(&ctx->devs->tree, dif, 0, 0, GFP_KERNEL);
-               up_write(&ctx->devs->rwsem);
+               down_write(&sbi->devs->rwsem);
+               ret = idr_alloc(&sbi->devs->tree, dif, 0, 0, GFP_KERNEL);
+               up_write(&sbi->devs->rwsem);
                if (ret < 0) {
                        kfree(dif->path);
                        kfree(dif);
                        return ret;
                }
-               ++ctx->devs->extra_devices;
+               ++sbi->devs->extra_devices;
                break;
 #ifdef CONFIG_EROFS_FS_ONDEMAND
        case Opt_fsid:
-               kfree(ctx->fsid);
-               ctx->fsid = kstrdup(param->string, GFP_KERNEL);
-               if (!ctx->fsid)
+               kfree(sbi->fsid);
+               sbi->fsid = kstrdup(param->string, GFP_KERNEL);
+               if (!sbi->fsid)
                        return -ENOMEM;
                break;
        case Opt_domain_id:
-               kfree(ctx->domain_id);
-               ctx->domain_id = kstrdup(param->string, GFP_KERNEL);
-               if (!ctx->domain_id)
+               kfree(sbi->domain_id);
+               sbi->domain_id = kstrdup(param->string, GFP_KERNEL);
+               if (!sbi->domain_id)
                        return -ENOMEM;
                break;
 #else
@@ -581,8 +581,7 @@ static const struct export_operations erofs_export_ops = {
 static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
 {
        struct inode *inode;
-       struct erofs_sb_info *sbi;
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
        int err;
 
        sb->s_magic = EROFS_SUPER_MAGIC;
@@ -590,19 +589,6 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_op = &erofs_sops;
 
-       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
-       if (!sbi)
-               return -ENOMEM;
-
-       sb->s_fs_info = sbi;
-       sbi->opt = ctx->opt;
-       sbi->devs = ctx->devs;
-       ctx->devs = NULL;
-       sbi->fsid = ctx->fsid;
-       ctx->fsid = NULL;
-       sbi->domain_id = ctx->domain_id;
-       ctx->domain_id = NULL;
-
        sbi->blkszbits = PAGE_SHIFT;
        if (erofs_is_fscache_mode(sb)) {
                sb->s_blocksize = PAGE_SIZE;
@@ -706,9 +692,9 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
 
 static int erofs_fc_get_tree(struct fs_context *fc)
 {
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *sbi = fc->s_fs_info;
 
-       if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && ctx->fsid)
+       if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
                return get_tree_nodev(fc, erofs_fc_fill_super);
 
        return get_tree_bdev(fc, erofs_fc_fill_super);
@@ -718,19 +704,19 @@ static int erofs_fc_reconfigure(struct fs_context *fc)
 {
        struct super_block *sb = fc->root->d_sb;
        struct erofs_sb_info *sbi = EROFS_SB(sb);
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *new_sbi = fc->s_fs_info;
 
        DBG_BUGON(!sb_rdonly(sb));
 
-       if (ctx->fsid || ctx->domain_id)
+       if (new_sbi->fsid || new_sbi->domain_id)
                erofs_info(sb, "ignoring reconfiguration for fsid|domain_id.");
 
-       if (test_opt(&ctx->opt, POSIX_ACL))
+       if (test_opt(&new_sbi->opt, POSIX_ACL))
                fc->sb_flags |= SB_POSIXACL;
        else
                fc->sb_flags &= ~SB_POSIXACL;
 
-       sbi->opt = ctx->opt;
+       sbi->opt = new_sbi->opt;
 
        fc->sb_flags |= SB_RDONLY;
        return 0;
@@ -761,12 +747,15 @@ static void erofs_free_dev_context(struct erofs_dev_context *devs)
 
 static void erofs_fc_free(struct fs_context *fc)
 {
-       struct erofs_fs_context *ctx = fc->fs_private;
+       struct erofs_sb_info *sbi = fc->s_fs_info;
 
-       erofs_free_dev_context(ctx->devs);
-       kfree(ctx->fsid);
-       kfree(ctx->domain_id);
-       kfree(ctx);
+       if (!sbi)
+               return;
+
+       erofs_free_dev_context(sbi->devs);
+       kfree(sbi->fsid);
+       kfree(sbi->domain_id);
+       kfree(sbi);
 }
 
 static const struct fs_context_operations erofs_context_ops = {
@@ -778,38 +767,35 @@ static const struct fs_context_operations erofs_context_ops = {
 
 static int erofs_init_fs_context(struct fs_context *fc)
 {
-       struct erofs_fs_context *ctx;
+       struct erofs_sb_info *sbi;
 
-       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
-       if (!ctx)
+       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+       if (!sbi)
                return -ENOMEM;
-       ctx->devs = kzalloc(sizeof(struct erofs_dev_context), GFP_KERNEL);
-       if (!ctx->devs) {
-               kfree(ctx);
+
+       sbi->devs = kzalloc(sizeof(struct erofs_dev_context), GFP_KERNEL);
+       if (!sbi->devs) {
+               kfree(sbi);
                return -ENOMEM;
        }
-       fc->fs_private = ctx;
+       fc->s_fs_info = sbi;
 
-       idr_init(&ctx->devs->tree);
-       init_rwsem(&ctx->devs->rwsem);
-       erofs_default_options(ctx);
+       idr_init(&sbi->devs->tree);
+       init_rwsem(&sbi->devs->rwsem);
+       erofs_default_options(sbi);
        fc->ops = &erofs_context_ops;
        return 0;
 }
 
 static void erofs_kill_sb(struct super_block *sb)
 {
-       struct erofs_sb_info *sbi;
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
 
-       if (erofs_is_fscache_mode(sb))
+       if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
                kill_anon_super(sb);
        else
                kill_block_super(sb);
 
-       sbi = EROFS_SB(sb);
-       if (!sbi)
-               return;
-
        erofs_free_dev_context(sbi->devs);
        fs_put_dax(sbi->dax_dev, NULL);
        erofs_fscache_unregister_fs(sb);
index 882b89edc52adb24e6f62dc2b778e186001293d4..f53ca4f7fceddd0b0e661f05105435b420e19430 100644 (file)
@@ -979,6 +979,34 @@ static __poll_t __ep_eventpoll_poll(struct file *file, poll_table *wait, int dep
        return res;
 }
 
+/*
+ * The ffd.file pointer may be in the process of being torn down due to
+ * being closed, but we may not have finished eventpoll_release() yet.
+ *
+ * Normally, even with the atomic_long_inc_not_zero, the file may have
+ * been free'd and then gotten re-allocated to something else (since
+ * files are not RCU-delayed, they are SLAB_TYPESAFE_BY_RCU).
+ *
+ * But for epoll, users hold the ep->mtx mutex, and as such any file in
+ * the process of being free'd will block in eventpoll_release_file()
+ * and thus the underlying file allocation will not be free'd, and the
+ * file re-use cannot happen.
+ *
+ * For the same reason we can avoid a rcu_read_lock() around the
+ * operation - 'ffd.file' cannot go away even if the refcount has
+ * reached zero (but we must still not call out to ->poll() functions
+ * etc).
+ */
+static struct file *epi_fget(const struct epitem *epi)
+{
+       struct file *file;
+
+       file = epi->ffd.file;
+       if (!atomic_long_inc_not_zero(&file->f_count))
+               file = NULL;
+       return file;
+}
+
 /*
  * Differs from ep_eventpoll_poll() in that internal callers already have
  * the ep->mtx so we need to start from depth=1, such that mutex_lock_nested()
@@ -987,14 +1015,22 @@ static __poll_t __ep_eventpoll_poll(struct file *file, poll_table *wait, int dep
 static __poll_t ep_item_poll(const struct epitem *epi, poll_table *pt,
                                 int depth)
 {
-       struct file *file = epi->ffd.file;
+       struct file *file = epi_fget(epi);
        __poll_t res;
 
+       /*
+        * We could return EPOLLERR | EPOLLHUP or something, but let's
+        * treat this more as "file doesn't exist, poll didn't happen".
+        */
+       if (!file)
+               return 0;
+
        pt->_key = epi->event.events;
        if (!is_file_epoll(file))
                res = vfs_poll(file, pt);
        else
                res = __ep_eventpoll_poll(file, pt, depth);
+       fput(file);
        return res & epi->event.events;
 }
 
index 077944d3c2c025fa9b74d041f64762ce4c969dcd..84572e11cc05f34ba3bfdf0190654c5d7a8961e0 100644 (file)
@@ -420,6 +420,7 @@ static void exfat_set_entry_type(struct exfat_dentry *ep, unsigned int type)
 static void exfat_init_stream_entry(struct exfat_dentry *ep,
                unsigned int start_clu, unsigned long long size)
 {
+       memset(ep, 0, sizeof(*ep));
        exfat_set_entry_type(ep, TYPE_STREAM);
        if (size == 0)
                ep->dentry.stream.flags = ALLOC_FAT_CHAIN;
@@ -457,6 +458,7 @@ void exfat_init_dir_entry(struct exfat_entry_set_cache *es,
        struct exfat_dentry *ep;
 
        ep = exfat_get_dentry_cached(es, ES_IDX_FILE);
+       memset(ep, 0, sizeof(*ep));
        exfat_set_entry_type(ep, type);
        exfat_set_entry_time(sbi, ts,
                        &ep->dentry.file.create_tz,
index cc00f1a7a1e18082af9e0e8ff28f5995de75f1ba..9adfc38ca7dac01ee004315a7b5d11486ee20f10 100644 (file)
@@ -51,7 +51,7 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
        clu.flags = ei->flags;
 
        ret = exfat_alloc_cluster(inode, new_num_clusters - num_clusters,
-                       &clu, IS_DIRSYNC(inode));
+                       &clu, inode_needs_sync(inode));
        if (ret)
                return ret;
 
@@ -77,12 +77,11 @@ out:
        ei->i_size_aligned = round_up(size, sb->s_blocksize);
        ei->i_size_ondisk = ei->i_size_aligned;
        inode->i_blocks = round_up(size, sbi->cluster_size) >> 9;
+       mark_inode_dirty(inode);
 
-       if (IS_DIRSYNC(inode))
+       if (IS_SYNC(inode))
                return write_inode_now(inode, 1);
 
-       mark_inode_dirty(inode);
-
        return 0;
 
 free_clu:
index 54d6ff22585cf1835e8aced5548dbac7c1b89757..28c51b0cc4db91a912d332deb4a53861a9b47227 100644 (file)
@@ -885,8 +885,7 @@ static int ext4_file_open(struct inode *inode, struct file *filp)
                        return ret;
        }
 
-       filp->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC |
-                       FMODE_DIO_PARALLEL_WRITE;
+       filp->f_mode |= FMODE_NOWAIT;
        return dquot_file_open(inode, filp);
 }
 
@@ -938,7 +937,6 @@ const struct file_operations ext4_file_operations = {
        .compat_ioctl   = ext4_compat_ioctl,
 #endif
        .mmap           = ext4_file_mmap,
-       .mmap_supported_flags = MAP_SYNC,
        .open           = ext4_file_open,
        .release        = ext4_release_file,
        .fsync          = ext4_sync_file,
@@ -946,6 +944,8 @@ const struct file_operations ext4_file_operations = {
        .splice_read    = ext4_file_splice_read,
        .splice_write   = iter_file_splice_write,
        .fallocate      = ext4_fallocate,
+       .fop_flags      = FOP_MMAP_SYNC | FOP_BUFFER_RASYNC |
+                         FOP_DIO_PARALLEL_WRITE,
 };
 
 const struct inode_operations ext4_file_inode_operations = {
index 044135796f2b6ebe86e56b69f57501e7567d761b..3fce1b80c419588ef4d8874ec93f2e1c21cb1caf 100644 (file)
@@ -1723,10 +1723,6 @@ static const struct constant_table ext4_param_dax[] = {
        {}
 };
 
-/* String parameter that allows empty argument */
-#define fsparam_string_empty(NAME, OPT) \
-       __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL)
-
 /*
  * Mount option specification
  * We don't use fsparam_flag_no because of the way we set the
index 1761ad125f97a37ebb7bb9ce5c35ff9decf8a130..2b65e09822d40482c22d38548697f3327cfb9a1c 100644 (file)
@@ -569,7 +569,7 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
        if (err)
                return err;
 
-       filp->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC;
+       filp->f_mode |= FMODE_NOWAIT;
        filp->f_mode |= FMODE_CAN_ODIRECT;
 
        return dquot_file_open(inode, filp);
@@ -5045,4 +5045,5 @@ const struct file_operations f2fs_file_operations = {
        .splice_read    = f2fs_file_splice_read,
        .splice_write   = iter_file_splice_write,
        .fadvise        = f2fs_file_fadvise,
+       .fop_flags      = FOP_BUFFER_RASYNC,
 };
index 54cc85d3338ed5afb12021e02a4fe6877aa675af..300e5d9ad913b588c1aa2a59cab4e2e8ab2ef5a7 100644 (file)
@@ -327,6 +327,22 @@ static long fcntl_set_rw_hint(struct file *file, unsigned int cmd,
        return 0;
 }
 
+/* Is the file descriptor a dup of the file? */
+static long f_dupfd_query(int fd, struct file *filp)
+{
+       CLASS(fd_raw, f)(fd);
+
+       /*
+        * We can do the 'fdput()' immediately, as the only thing that
+        * matters is the pointer value which isn't changed by the fdput.
+        *
+        * Technically we didn't need a ref at all, and 'fdget()' was
+        * overkill, but given our lockless file pointer lookup, the
+        * alternatives are complicated.
+        */
+       return f.file == filp;
+}
+
 static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                struct file *filp)
 {
@@ -342,6 +358,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
        case F_DUPFD_CLOEXEC:
                err = f_dupfd(argi, filp, O_CLOEXEC);
                break;
+       case F_DUPFD_QUERY:
+               err = f_dupfd_query(argi, filp);
+               break;
        case F_GETFD:
                err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
                break;
@@ -446,6 +465,7 @@ static int check_fcntl_cmd(unsigned cmd)
        switch (cmd) {
        case F_DUPFD:
        case F_DUPFD_CLOEXEC:
+       case F_DUPFD_QUERY:
        case F_GETFD:
        case F_SETFD:
        case F_GETFL:
index 57a12614addfd434f981a5b8c981a48ae1a71ceb..8a7f86c2139a7fcd9a43b282c8408e046eaaa034 100644 (file)
@@ -36,7 +36,7 @@ static long do_sys_name_to_handle(const struct path *path,
        if (f_handle.handle_bytes > MAX_HANDLE_SZ)
                return -EINVAL;
 
-       handle = kzalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
+       handle = kzalloc(struct_size(handle, f_handle, f_handle.handle_bytes),
                         GFP_KERNEL);
        if (!handle)
                return -ENOMEM;
@@ -71,7 +71,7 @@ static long do_sys_name_to_handle(const struct path *path,
        /* copy the mount id */
        if (put_user(real_mount(path->mnt)->mnt_id, mnt_id) ||
            copy_to_user(ufh, handle,
-                        sizeof(struct file_handle) + handle_bytes))
+                        struct_size(handle, f_handle, handle_bytes)))
                retval = -EFAULT;
        kfree(handle);
        return retval;
@@ -192,7 +192,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh,
                retval = -EINVAL;
                goto out_err;
        }
-       handle = kmalloc(sizeof(struct file_handle) + f_handle.handle_bytes,
+       handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes),
                         GFP_KERNEL);
        if (!handle) {
                retval = -ENOMEM;
index 42e03b6b1cc7a88791cf117a02f0b9242ac22629..fabe60778658068b0cd2ff1204ccb57db0c61c1f 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/vfs.h>
-#include <linux/mount.h>
+#include <linux/fs_context.h>
 
 #include "vxfs.h"
 #include "vxfs_extern.h"
@@ -91,10 +91,10 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
        return 0;
 }
 
-static int vxfs_remount(struct super_block *sb, int *flags, char *data)
+static int vxfs_reconfigure(struct fs_context *fc)
 {
-       sync_filesystem(sb);
-       *flags |= SB_RDONLY;
+       sync_filesystem(fc->root->d_sb);
+       fc->sb_flags |= SB_RDONLY;
        return 0;
 }
 
@@ -120,24 +120,24 @@ static const struct super_operations vxfs_super_ops = {
        .evict_inode            = vxfs_evict_inode,
        .put_super              = vxfs_put_super,
        .statfs                 = vxfs_statfs,
-       .remount_fs             = vxfs_remount,
 };
 
-static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
+static int vxfs_try_sb_magic(struct super_block *sbp, struct fs_context *fc,
                unsigned blk, __fs32 magic)
 {
        struct buffer_head *bp;
        struct vxfs_sb *rsbp;
        struct vxfs_sb_info *infp = VXFS_SBI(sbp);
+       int silent = fc->sb_flags & SB_SILENT;
        int rc = -ENOMEM;
 
        bp = sb_bread(sbp, blk);
        do {
                if (!bp || !buffer_mapped(bp)) {
                        if (!silent) {
-                               printk(KERN_WARNING
-                                       "vxfs: unable to read disk superblock at %u\n",
-                                       blk);
+                               warnf(fc,
+                                     "vxfs: unable to read disk superblock at %u",
+                                     blk);
                        }
                        break;
                }
@@ -146,9 +146,9 @@ static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
                rsbp = (struct vxfs_sb *)bp->b_data;
                if (rsbp->vs_magic != magic) {
                        if (!silent)
-                               printk(KERN_NOTICE
-                                       "vxfs: WRONG superblock magic %08x at %u\n",
-                                       rsbp->vs_magic, blk);
+                               infof(fc,
+                                     "vxfs: WRONG superblock magic %08x at %u",
+                                     rsbp->vs_magic, blk);
                        break;
                }
 
@@ -169,8 +169,7 @@ static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
 /**
  * vxfs_fill_super - read superblock into memory and initialize filesystem
  * @sbp:               VFS superblock (to fill)
- * @dp:                        fs private mount data
- * @silent:            do not complain loudly when sth is wrong
+ * @fc:                        filesytem context
  *
  * Description:
  *   We are called on the first mount of a filesystem to read the
@@ -182,26 +181,27 @@ static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
  * Locking:
  *   We are under @sbp->s_lock.
  */
-static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
+static int vxfs_fill_super(struct super_block *sbp, struct fs_context *fc)
 {
        struct vxfs_sb_info     *infp;
        struct vxfs_sb          *rsbp;
        u_long                  bsize;
        struct inode *root;
        int ret = -EINVAL;
+       int silent = fc->sb_flags & SB_SILENT;
        u32 j;
 
        sbp->s_flags |= SB_RDONLY;
 
        infp = kzalloc(sizeof(*infp), GFP_KERNEL);
        if (!infp) {
-               printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
+               warnf(fc, "vxfs: unable to allocate incore superblock");
                return -ENOMEM;
        }
 
        bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
        if (!bsize) {
-               printk(KERN_WARNING "vxfs: unable to set blocksize\n");
+               warnf(fc, "vxfs: unable to set blocksize");
                goto out;
        }
 
@@ -210,24 +210,24 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
        sbp->s_time_min = 0;
        sbp->s_time_max = U32_MAX;
 
-       if (!vxfs_try_sb_magic(sbp, silent, 1,
+       if (!vxfs_try_sb_magic(sbp, fc, 1,
                        (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
                /* Unixware, x86 */
                infp->byte_order = VXFS_BO_LE;
-       } else if (!vxfs_try_sb_magic(sbp, silent, 8,
+       } else if (!vxfs_try_sb_magic(sbp, fc, 8,
                        (__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
                /* HP-UX, parisc */
                infp->byte_order = VXFS_BO_BE;
        } else {
                if (!silent)
-                       printk(KERN_NOTICE "vxfs: can't find superblock.\n");
+                       infof(fc, "vxfs: can't find superblock.");
                goto out;
        }
 
        rsbp = infp->vsi_raw;
        j = fs32_to_cpu(infp, rsbp->vs_version);
        if ((j < 2 || j > 4) && !silent) {
-               printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
+               infof(fc, "vxfs: unsupported VxFS version (%d)", j);
                goto out;
        }
 
@@ -244,17 +244,17 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 
        j = fs32_to_cpu(infp, rsbp->vs_bsize);
        if (!sb_set_blocksize(sbp, j)) {
-               printk(KERN_WARNING "vxfs: unable to set final block size\n");
+               warnf(fc, "vxfs: unable to set final block size");
                goto out;
        }
 
        if (vxfs_read_olt(sbp, bsize)) {
-               printk(KERN_WARNING "vxfs: unable to read olt\n");
+               warnf(fc, "vxfs: unable to read olt");
                goto out;
        }
 
        if (vxfs_read_fshead(sbp)) {
-               printk(KERN_WARNING "vxfs: unable to read fshead\n");
+               warnf(fc, "vxfs: unable to read fshead");
                goto out;
        }
 
@@ -265,7 +265,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
        }
        sbp->s_root = d_make_root(root);
        if (!sbp->s_root) {
-               printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
+               warnf(fc, "vxfs: unable to get root dentry.");
                goto out_free_ilist;
        }
 
@@ -284,18 +284,29 @@ out:
 /*
  * The usual module blurb.
  */
-static struct dentry *vxfs_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int vxfs_get_tree(struct fs_context *fc)
 {
-       return mount_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
+       return get_tree_bdev(fc, vxfs_fill_super);
+}
+
+static const struct fs_context_operations vxfs_context_ops = {
+       .get_tree       = vxfs_get_tree,
+       .reconfigure    = vxfs_reconfigure,
+};
+
+static int vxfs_init_fs_context(struct fs_context *fc)
+{
+       fc->ops = &vxfs_context_ops;
+
+       return 0;
 }
 
 static struct file_system_type vxfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "vxfs",
-       .mount          = vxfs_mount,
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
+       .init_fs_context = vxfs_init_fs_context,
 };
 MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
 MODULE_ALIAS("vxfs");
index e4f17c53ddfcf345bda9961f239be00a98a528f4..92a5b8283528c0c6b8f5b69a89a0bcb40cfd2225 100644 (file)
@@ -166,8 +166,7 @@ static void wb_wakeup_delayed(struct bdi_writeback *wb)
        spin_unlock_irq(&wb->work_lock);
 }
 
-static void finish_writeback_work(struct bdi_writeback *wb,
-                                 struct wb_writeback_work *work)
+static void finish_writeback_work(struct wb_writeback_work *work)
 {
        struct wb_completion *done = work->done;
 
@@ -196,7 +195,7 @@ static void wb_queue_work(struct bdi_writeback *wb,
                list_add_tail(&work->list, &wb->work_list);
                mod_delayed_work(bdi_wq, &wb->dwork, 0);
        } else
-               finish_writeback_work(wb, work);
+               finish_writeback_work(work);
 
        spin_unlock_irq(&wb->work_lock);
 }
@@ -1561,7 +1560,8 @@ static void inode_sleep_on_writeback(struct inode *inode)
  * thread's back can have unexpected consequences.
  */
 static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
-                         struct writeback_control *wbc)
+                         struct writeback_control *wbc,
+                         unsigned long dirtied_before)
 {
        if (inode->i_state & I_FREEING)
                return;
@@ -1594,7 +1594,8 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
                 * We didn't write back all the pages.  nfs_writepages()
                 * sometimes bales out without doing anything.
                 */
-               if (wbc->nr_to_write <= 0) {
+               if (wbc->nr_to_write <= 0 &&
+                   !inode_dirtied_after(inode, dirtied_before)) {
                        /* Slice used up. Queue for next turn. */
                        requeue_io(inode, wb);
                } else {
@@ -1862,6 +1863,11 @@ static long writeback_sb_inodes(struct super_block *sb,
        unsigned long start_time = jiffies;
        long write_chunk;
        long total_wrote = 0;  /* count both pages and inodes */
+       unsigned long dirtied_before = jiffies;
+
+       if (work->for_kupdate)
+               dirtied_before = jiffies -
+                       msecs_to_jiffies(dirty_expire_interval * 10);
 
        while (!list_empty(&wb->b_io)) {
                struct inode *inode = wb_inode(wb->b_io.prev);
@@ -1967,7 +1973,7 @@ static long writeback_sb_inodes(struct super_block *sb,
                spin_lock(&inode->i_lock);
                if (!(inode->i_state & I_DIRTY_ALL))
                        total_wrote++;
-               requeue_inode(inode, tmp_wb, &wbc);
+               requeue_inode(inode, tmp_wb, &wbc, dirtied_before);
                inode_sync_complete(inode);
                spin_unlock(&inode->i_lock);
 
@@ -2069,6 +2075,7 @@ static long wb_writeback(struct bdi_writeback *wb,
        struct inode *inode;
        long progress;
        struct blk_plug plug;
+       bool queued = false;
 
        blk_start_plug(&plug);
        for (;;) {
@@ -2098,21 +2105,24 @@ static long wb_writeback(struct bdi_writeback *wb,
 
                spin_lock(&wb->list_lock);
 
-               /*
-                * Kupdate and background works are special and we want to
-                * include all inodes that need writing. Livelock avoidance is
-                * handled by these works yielding to any other work so we are
-                * safe.
-                */
-               if (work->for_kupdate) {
-                       dirtied_before = jiffies -
-                               msecs_to_jiffies(dirty_expire_interval * 10);
-               } else if (work->for_background)
-                       dirtied_before = jiffies;
-
                trace_writeback_start(wb, work);
-               if (list_empty(&wb->b_io))
+               if (list_empty(&wb->b_io)) {
+                       /*
+                        * Kupdate and background works are special and we want
+                        * to include all inodes that need writing. Livelock
+                        * avoidance is handled by these works yielding to any
+                        * other work so we are safe.
+                        */
+                       if (work->for_kupdate) {
+                               dirtied_before = jiffies -
+                                       msecs_to_jiffies(dirty_expire_interval *
+                                                        10);
+                       } else if (work->for_background)
+                               dirtied_before = jiffies;
+
                        queue_io(wb, work, dirtied_before);
+                       queued = true;
+               }
                if (work->sb)
                        progress = writeback_sb_inodes(work->sb, wb, work);
                else
@@ -2127,7 +2137,7 @@ static long wb_writeback(struct bdi_writeback *wb,
                 * mean the overall work is done. So we keep looping as long
                 * as made some progress on cleaning pages or inodes.
                 */
-               if (progress) {
+               if (progress || !queued) {
                        spin_unlock(&wb->list_lock);
                        continue;
                }
@@ -2262,7 +2272,7 @@ static long wb_do_writeback(struct bdi_writeback *wb)
        while ((work = get_next_work_item(wb)) != NULL) {
                trace_writeback_exec(wb, work);
                wrote += wb_writeback(wb, work);
-               finish_writeback_work(wb, work);
+               finish_writeback_work(work);
        }
 
        /*
@@ -2322,8 +2332,7 @@ void wb_workfn(struct work_struct *work)
 }
 
 /*
- * Start writeback of `nr_pages' pages on this bdi. If `nr_pages' is zero,
- * write back the whole world.
+ * Start writeback of all dirty pages on this bdi.
  */
 static void __wakeup_flusher_threads_bdi(struct backing_dev_info *bdi,
                                         enum wb_reason reason)
@@ -2726,7 +2735,7 @@ EXPORT_SYMBOL(writeback_inodes_sb_nr);
  */
 void writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)
 {
-       return writeback_inodes_sb_nr(sb, get_nr_dirty_pages(), reason);
+       writeback_inodes_sb_nr(sb, get_nr_dirty_pages(), reason);
 }
 EXPORT_SYMBOL(writeback_inodes_sb);
 
index 1567f0323858bfce0ef4542d055c6111f936aa89..9666d13884ce59175a844f85082c442cadbdf354 100644 (file)
@@ -225,7 +225,7 @@ int fuse_backing_open(struct fuse_conn *fc, struct fuse_backing_map *map)
                goto out;
 
        res = -EINVAL;
-       if (map->flags)
+       if (map->flags || map->padding)
                goto out;
 
        file = fget(map->fd);
index 322af827a2329f9af0ee445116f1ef84114b2b4c..bb3e941b95031ac199532e6f2057f3df77c2939d 100644 (file)
@@ -170,7 +170,7 @@ static ssize_t tag_show(struct kobject *kobj,
 {
        struct virtio_fs *fs = container_of(kobj, struct virtio_fs, kobj);
 
-       return sysfs_emit(buf, fs->tag);
+       return sysfs_emit(buf, "%s\n", fs->tag);
 }
 
 static struct kobj_attribute virtio_fs_tag_attr = __ATTR_RO(tag);
index 6502c7e776d195e1d004908964f74ce5a76d6db2..34ac73cc36b1cf49cf2cce951355c7837ad6e350 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/sched/mm.h>
 
 static const struct address_space_operations hugetlbfs_aops;
-const struct file_operations hugetlbfs_file_operations;
+static const struct file_operations hugetlbfs_file_operations;
 static const struct inode_operations hugetlbfs_dir_inode_operations;
 static const struct inode_operations hugetlbfs_inode_operations;
 
@@ -1301,13 +1301,14 @@ static void init_once(void *foo)
        inode_init_once(&ei->vfs_inode);
 }
 
-const struct file_operations hugetlbfs_file_operations = {
+static const struct file_operations hugetlbfs_file_operations = {
        .read_iter              = hugetlbfs_read_iter,
        .mmap                   = hugetlbfs_file_mmap,
        .fsync                  = noop_fsync,
        .get_unmapped_area      = hugetlb_get_unmapped_area,
        .llseek                 = default_llseek,
        .fallocate              = hugetlbfs_fallocate,
+       .fop_flags              = FOP_HUGE_PAGES,
 };
 
 static const struct inode_operations hugetlbfs_dir_inode_operations = {
index 4e8e41c8b3c0e41c97ed544bfafbef4113f4fbd5..41c8f0c68ef564960a4341f605d9da135e9f14ef 100644 (file)
@@ -824,12 +824,11 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
 
 out_unlock:
        __iomap_put_folio(iter, pos, 0, folio);
-       iomap_write_failed(iter->inode, pos, len);
 
        return status;
 }
 
-static size_t __iomap_write_end(struct inode *inode, loff_t pos, size_t len,
+static bool __iomap_write_end(struct inode *inode, loff_t pos, size_t len,
                size_t copied, struct folio *folio)
 {
        flush_dcache_folio(folio);
@@ -846,14 +845,14 @@ static size_t __iomap_write_end(struct inode *inode, loff_t pos, size_t len,
         * redo the whole thing.
         */
        if (unlikely(copied < len && !folio_test_uptodate(folio)))
-               return 0;
+               return false;
        iomap_set_range_uptodate(folio, offset_in_folio(folio, pos), len);
        iomap_set_range_dirty(folio, offset_in_folio(folio, pos), copied);
        filemap_dirty_folio(inode->i_mapping, folio);
-       return copied;
+       return true;
 }
 
-static size_t iomap_write_end_inline(const struct iomap_iter *iter,
+static void iomap_write_end_inline(const struct iomap_iter *iter,
                struct folio *folio, loff_t pos, size_t copied)
 {
        const struct iomap *iomap = &iter->iomap;
@@ -868,42 +867,32 @@ static size_t iomap_write_end_inline(const struct iomap_iter *iter,
        kunmap_local(addr);
 
        mark_inode_dirty(iter->inode);
-       return copied;
 }
 
-/* Returns the number of bytes copied.  May be 0.  Cannot be an errno. */
-static size_t iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len,
+/*
+ * Returns true if all copied bytes have been written to the pagecache,
+ * otherwise return false.
+ */
+static bool iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len,
                size_t copied, struct folio *folio)
 {
        const struct iomap *srcmap = iomap_iter_srcmap(iter);
-       loff_t old_size = iter->inode->i_size;
-       size_t ret;
 
        if (srcmap->type == IOMAP_INLINE) {
-               ret = iomap_write_end_inline(iter, folio, pos, copied);
-       } else if (srcmap->flags & IOMAP_F_BUFFER_HEAD) {
-               ret = block_write_end(NULL, iter->inode->i_mapping, pos, len,
-                               copied, &folio->page, NULL);
-       } else {
-               ret = __iomap_write_end(iter->inode, pos, len, copied, folio);
+               iomap_write_end_inline(iter, folio, pos, copied);
+               return true;
        }
 
-       /*
-        * Update the in-memory inode size after copying the data into the page
-        * cache.  It's up to the file system to write the updated size to disk,
-        * preferably after I/O completion so that no stale data is exposed.
-        */
-       if (pos + ret > old_size) {
-               i_size_write(iter->inode, pos + ret);
-               iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
+       if (srcmap->flags & IOMAP_F_BUFFER_HEAD) {
+               size_t bh_written;
+
+               bh_written = block_write_end(NULL, iter->inode->i_mapping, pos,
+                                       len, copied, &folio->page, NULL);
+               WARN_ON_ONCE(bh_written != copied && bh_written != 0);
+               return bh_written == copied;
        }
-       __iomap_put_folio(iter, pos, ret, folio);
 
-       if (old_size < pos)
-               pagecache_isize_extended(iter->inode, old_size, pos);
-       if (ret < len)
-               iomap_write_failed(iter->inode, pos + ret, len - ret);
-       return ret;
+       return __iomap_write_end(iter->inode, pos, len, copied, folio);
 }
 
 static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
@@ -911,16 +900,18 @@ static loff_t iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
        loff_t length = iomap_length(iter);
        size_t chunk = PAGE_SIZE << MAX_PAGECACHE_ORDER;
        loff_t pos = iter->pos;
-       ssize_t written = 0;
+       ssize_t total_written = 0;
        long status = 0;
        struct address_space *mapping = iter->inode->i_mapping;
        unsigned int bdp_flags = (iter->flags & IOMAP_NOWAIT) ? BDP_ASYNC : 0;
 
        do {
                struct folio *folio;
+               loff_t old_size;
                size_t offset;          /* Offset into folio */
                size_t bytes;           /* Bytes to write to folio */
                size_t copied;          /* Bytes copied from user */
+               size_t written;         /* Bytes have been written */
 
                bytes = iov_iter_count(i);
 retry:
@@ -950,8 +941,10 @@ retry:
                }
 
                status = iomap_write_begin(iter, pos, bytes, &folio);
-               if (unlikely(status))
+               if (unlikely(status)) {
+                       iomap_write_failed(iter->inode, pos, bytes);
                        break;
+               }
                if (iter->iomap.flags & IOMAP_F_STALE)
                        break;
 
@@ -963,19 +956,37 @@ retry:
                        flush_dcache_folio(folio);
 
                copied = copy_folio_from_iter_atomic(folio, offset, bytes, i);
-               status = iomap_write_end(iter, pos, bytes, copied, folio);
+               written = iomap_write_end(iter, pos, bytes, copied, folio) ?
+                         copied : 0;
+
+               /*
+                * Update the in-memory inode size after copying the data into
+                * the page cache.  It's up to the file system to write the
+                * updated size to disk, preferably after I/O completion so that
+                * no stale data is exposed.  Only once that's done can we
+                * unlock and release the folio.
+                */
+               old_size = iter->inode->i_size;
+               if (pos + written > old_size) {
+                       i_size_write(iter->inode, pos + written);
+                       iter->iomap.flags |= IOMAP_F_SIZE_CHANGED;
+               }
+               __iomap_put_folio(iter, pos, written, folio);
 
-               if (unlikely(copied != status))
-                       iov_iter_revert(i, copied - status);
+               if (old_size < pos)
+                       pagecache_isize_extended(iter->inode, old_size, pos);
 
                cond_resched();
-               if (unlikely(status == 0)) {
+               if (unlikely(written == 0)) {
                        /*
                         * A short copy made iomap_write_end() reject the
                         * thing entirely.  Might be memory poisoning
                         * halfway through, might be a race with munmap,
                         * might be severe memory pressure.
                         */
+                       iomap_write_failed(iter->inode, pos, bytes);
+                       iov_iter_revert(i, copied);
+
                        if (chunk > PAGE_SIZE)
                                chunk /= 2;
                        if (copied) {
@@ -983,17 +994,17 @@ retry:
                                goto retry;
                        }
                } else {
-                       pos += status;
-                       written += status;
-                       length -= status;
+                       pos += written;
+                       total_written += written;
+                       length -= written;
                }
        } while (iov_iter_count(i) && length);
 
        if (status == -EAGAIN) {
-               iov_iter_revert(i, written);
+               iov_iter_revert(i, total_written);
                return -EAGAIN;
        }
-       return written ? written : status;
+       return total_written ? total_written : status;
 }
 
 ssize_t
@@ -1322,6 +1333,7 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
                int status;
                size_t offset;
                size_t bytes = min_t(u64, SIZE_MAX, length);
+               bool ret;
 
                status = iomap_write_begin(iter, pos, bytes, &folio);
                if (unlikely(status))
@@ -1333,8 +1345,9 @@ static loff_t iomap_unshare_iter(struct iomap_iter *iter)
                if (bytes > folio_size(folio) - offset)
                        bytes = folio_size(folio) - offset;
 
-               bytes = iomap_write_end(iter, pos, bytes, bytes, folio);
-               if (WARN_ON_ONCE(bytes == 0))
+               ret = iomap_write_end(iter, pos, bytes, bytes, folio);
+               __iomap_put_folio(iter, pos, bytes, folio);
+               if (WARN_ON_ONCE(!ret))
                        return -EIO;
 
                cond_resched();
@@ -1383,6 +1396,7 @@ static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
                int status;
                size_t offset;
                size_t bytes = min_t(u64, SIZE_MAX, length);
+               bool ret;
 
                status = iomap_write_begin(iter, pos, bytes, &folio);
                if (status)
@@ -1397,8 +1411,9 @@ static loff_t iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
                folio_zero_range(folio, offset, bytes);
                folio_mark_accessed(folio);
 
-               bytes = iomap_write_end(iter, pos, bytes, bytes, folio);
-               if (WARN_ON_ONCE(bytes == 0))
+               ret = iomap_write_end(iter, pos, bytes, bytes, folio);
+               __iomap_put_folio(iter, pos, bytes, folio);
+               if (WARN_ON_ONCE(!ret))
                        return -EIO;
 
                pos += bytes;
@@ -1958,18 +1973,13 @@ static int iomap_writepage_map(struct iomap_writepage_ctx *wpc,
        return error;
 }
 
-static int iomap_do_writepage(struct folio *folio,
-               struct writeback_control *wbc, void *data)
-{
-       return iomap_writepage_map(data, wbc, folio);
-}
-
 int
 iomap_writepages(struct address_space *mapping, struct writeback_control *wbc,
                struct iomap_writepage_ctx *wpc,
                const struct iomap_writeback_ops *ops)
 {
-       int                     ret;
+       struct folio *folio = NULL;
+       int error;
 
        /*
         * Writeback from reclaim context should never happen except in the case
@@ -1980,8 +1990,9 @@ iomap_writepages(struct address_space *mapping, struct writeback_control *wbc,
                return -EIO;
 
        wpc->ops = ops;
-       ret = write_cache_pages(mapping, wbc, iomap_do_writepage, wpc);
-       return iomap_submit_ioend(wpc, ret);
+       while ((folio = writeback_iter(mapping, wbc, folio, &error)))
+               error = iomap_writepage_map(wpc, wbc, folio);
+       return iomap_submit_ioend(wpc, error);
 }
 EXPORT_SYMBOL_GPL(iomap_writepages);
 
index 00224f3a8d6e71ff5e23d067c9fde9c7aee064cb..defb4162c3d5b51d9bd62d818b33b0eee1773cc6 100644 (file)
@@ -1110,6 +1110,9 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
                return rc;
 
        request = PAD(sizeof(struct jffs2_raw_xattr) + strlen(xname) + 1 + size);
+       if (request > c->sector_size - c->cleanmarker_size)
+               return -ERANGE;
+
        rc = jffs2_reserve_space(c, request, &length,
                                 ALLOC_NORMAL, JFFS2_SUMMARY_XATTR_SIZE);
        if (rc) {
index 3a6f2cb364f8cbcc9fa78d6a0a45519ad6fcd696..b635ee5adbccede861d2fa88d7a75da496baea2a 100644 (file)
@@ -295,6 +295,18 @@ int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry)
        return 0;
 }
 
+static int simple_offset_replace(struct offset_ctx *octx, struct dentry *dentry,
+                                long offset)
+{
+       int ret;
+
+       ret = mtree_store(&octx->mt, offset, dentry, GFP_KERNEL);
+       if (ret)
+               return ret;
+       offset_set(dentry, offset);
+       return 0;
+}
+
 /**
  * simple_offset_remove - Remove an entry to a directory's offset map
  * @octx: directory offset ctx to be updated
@@ -345,6 +357,36 @@ int simple_offset_empty(struct dentry *dentry)
        return ret;
 }
 
+/**
+ * simple_offset_rename - handle directory offsets for rename
+ * @old_dir: parent directory of source entry
+ * @old_dentry: dentry of source entry
+ * @new_dir: parent_directory of destination entry
+ * @new_dentry: dentry of destination
+ *
+ * Caller provides appropriate serialization.
+ *
+ * User space expects the directory offset value of the replaced
+ * (new) directory entry to be unchanged after a rename.
+ *
+ * Returns zero on success, a negative errno value on failure.
+ */
+int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry,
+                        struct inode *new_dir, struct dentry *new_dentry)
+{
+       struct offset_ctx *old_ctx = old_dir->i_op->get_offset_ctx(old_dir);
+       struct offset_ctx *new_ctx = new_dir->i_op->get_offset_ctx(new_dir);
+       long new_offset = dentry2offset(new_dentry);
+
+       simple_offset_remove(old_ctx, old_dentry);
+
+       if (new_offset) {
+               offset_set(new_dentry, 0);
+               return simple_offset_replace(new_ctx, old_dentry, new_offset);
+       }
+       return simple_offset_add(new_ctx, old_dentry);
+}
+
 /**
  * simple_offset_rename_exchange - exchange rename with directory offsets
  * @old_dir: parent of dentry being moved
@@ -352,6 +394,9 @@ int simple_offset_empty(struct dentry *dentry)
  * @new_dir: destination parent
  * @new_dentry: destination dentry
  *
+ * This API preserves the directory offset values. Caller provides
+ * appropriate serialization.
+ *
  * Returns zero on success. Otherwise a negative errno is returned and the
  * rename is rolled back.
  */
@@ -369,11 +414,11 @@ int simple_offset_rename_exchange(struct inode *old_dir,
        simple_offset_remove(old_ctx, old_dentry);
        simple_offset_remove(new_ctx, new_dentry);
 
-       ret = simple_offset_add(new_ctx, old_dentry);
+       ret = simple_offset_replace(new_ctx, old_dentry, new_index);
        if (ret)
                goto out_restore;
 
-       ret = simple_offset_add(old_ctx, new_dentry);
+       ret = simple_offset_replace(old_ctx, new_dentry, old_index);
        if (ret) {
                simple_offset_remove(new_ctx, old_dentry);
                goto out_restore;
@@ -388,10 +433,8 @@ int simple_offset_rename_exchange(struct inode *old_dir,
        return 0;
 
 out_restore:
-       offset_set(old_dentry, old_index);
-       mtree_store(&old_ctx->mt, old_index, old_dentry, GFP_KERNEL);
-       offset_set(new_dentry, new_index);
-       mtree_store(&new_ctx->mt, new_index, new_dentry, GFP_KERNEL);
+       (void)simple_offset_replace(old_ctx, old_dentry, old_index);
+       (void)simple_offset_replace(new_ctx, new_dentry, new_index);
        return ret;
 }
 
index 7cbd2b9f4d115c4406a691b953477113a5bde4f1..7f9a2d8aa420f14a56865525f1e3889a99a5d0e0 100644 (file)
 #include <linux/mpage.h>
 #include <linux/vfs.h>
 #include <linux/writeback.h>
+#include <linux/fs_context.h>
 
 static int minix_write_inode(struct inode *inode,
                struct writeback_control *wbc);
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
-static int minix_remount (struct super_block * sb, int * flags, char * data);
 
 static void minix_evict_inode(struct inode *inode)
 {
@@ -111,19 +111,19 @@ static const struct super_operations minix_sops = {
        .evict_inode    = minix_evict_inode,
        .put_super      = minix_put_super,
        .statfs         = minix_statfs,
-       .remount_fs     = minix_remount,
 };
 
-static int minix_remount (struct super_block * sb, int * flags, char * data)
+static int minix_reconfigure(struct fs_context *fc)
 {
-       struct minix_sb_info * sbi = minix_sb(sb);
        struct minix_super_block * ms;
+       struct super_block *sb = fc->root->d_sb;
+       struct minix_sb_info * sbi = sb->s_fs_info;
 
        sync_filesystem(sb);
        ms = sbi->s_ms;
-       if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
+       if ((bool)(fc->sb_flags & SB_RDONLY) == sb_rdonly(sb))
                return 0;
-       if (*flags & SB_RDONLY) {
+       if (fc->sb_flags & SB_RDONLY) {
                if (ms->s_state & MINIX_VALID_FS ||
                    !(sbi->s_mount_state & MINIX_VALID_FS))
                        return 0;
@@ -170,7 +170,7 @@ static bool minix_check_superblock(struct super_block *sb)
        return true;
 }
 
-static int minix_fill_super(struct super_block *s, void *data, int silent)
+static int minix_fill_super(struct super_block *s, struct fs_context *fc)
 {
        struct buffer_head *bh;
        struct buffer_head **map;
@@ -180,6 +180,7 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
        struct inode *root_inode;
        struct minix_sb_info *sbi;
        int ret = -EINVAL;
+       int silent = fc->sb_flags & SB_SILENT;
 
        sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL);
        if (!sbi)
@@ -371,6 +372,23 @@ out:
        return ret;
 }
 
+static int minix_get_tree(struct fs_context *fc)
+{
+        return get_tree_bdev(fc, minix_fill_super);
+}
+
+static const struct fs_context_operations minix_context_ops = {
+       .get_tree       = minix_get_tree,
+       .reconfigure    = minix_reconfigure,
+};
+
+static int minix_init_fs_context(struct fs_context *fc)
+{
+       fc->ops = &minix_context_ops;
+
+       return 0;
+}
+
 static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct super_block *sb = dentry->d_sb;
@@ -680,18 +698,12 @@ void minix_truncate(struct inode * inode)
                V2_minix_truncate(inode);
 }
 
-static struct dentry *minix_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
-{
-       return mount_bdev(fs_type, flags, dev_name, data, minix_fill_super);
-}
-
 static struct file_system_type minix_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "minix",
-       .mount          = minix_mount,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV,
+       .owner                  = THIS_MODULE,
+       .name                   = "minix",
+       .kill_sb                = kill_block_super,
+       .fs_flags               = FS_REQUIRES_DEV,
+       .init_fs_context        = minix_init_fs_context,
 };
 MODULE_ALIAS_FS("minix");
 
index c5b2a25be7d048b613a11ef77b6f2f37ec1d0142..cb5dde0e309f7a2d27aae1d00d0f12da4064e92e 100644 (file)
@@ -2422,6 +2422,14 @@ static const char *path_init(struct nameidata *nd, unsigned flags)
                if (!f.file)
                        return ERR_PTR(-EBADF);
 
+               if (flags & LOOKUP_LINKAT_EMPTY) {
+                       if (f.file->f_cred != current_cred() &&
+                           !ns_capable(f.file->f_cred->user_ns, CAP_DAC_READ_SEARCH)) {
+                               fdput(f);
+                               return ERR_PTR(-ENOENT);
+                       }
+               }
+
                dentry = f.file->f_path.dentry;
 
                if (*s && unlikely(!d_can_lookup(dentry))) {
@@ -4641,14 +4649,13 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
                goto out_putnames;
        }
        /*
-        * To use null names we require CAP_DAC_READ_SEARCH
+        * To use null names we require CAP_DAC_READ_SEARCH or
+        * that the open-time creds of the dfd matches current.
         * This ensures that not everyone will be able to create
-        * handlink using the passed filedescriptor.
+        * a hardlink using the passed file descriptor.
         */
-       if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH)) {
-               error = -ENOENT;
-               goto out_putnames;
-       }
+       if (flags & AT_EMPTY_PATH)
+               how |= LOOKUP_LINKAT_EMPTY;
 
        if (flags & AT_SYMLINK_FOLLOW)
                how |= LOOKUP_FOLLOW;
index d4d1d799819ec4c92807449aebeb38e744d43991..8e6781e0b10b18b7986a3763b7fcfe268c9e6538 100644 (file)
@@ -11,7 +11,8 @@ netfs-y := \
        main.o \
        misc.o \
        objects.o \
-       output.o
+       write_collect.o \
+       write_issue.o
 
 netfs-$(CONFIG_NETFS_STATS) += stats.o
 
index 3298c29b5548398c0026ccf6ab30c32cb290070d..a6bb03bea920cba098447a1cd50ec84ed96728a3 100644 (file)
 #include "internal.h"
 
 /*
- * Unlock the folios in a read operation.  We need to set PG_fscache on any
+ * Unlock the folios in a read operation.  We need to set PG_writeback on any
  * folios we're going to write back before we unlock them.
+ *
+ * Note that if the deprecated NETFS_RREQ_USE_PGPRIV2 is set then we use
+ * PG_private_2 and do a direct write to the cache from here instead.
  */
 void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
 {
@@ -48,14 +51,14 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
        xas_for_each(&xas, folio, last_page) {
                loff_t pg_end;
                bool pg_failed = false;
-               bool folio_started;
+               bool wback_to_cache = false;
+               bool folio_started = false;
 
                if (xas_retry(&xas, folio))
                        continue;
 
                pg_end = folio_pos(folio) + folio_size(folio) - 1;
 
-               folio_started = false;
                for (;;) {
                        loff_t sreq_end;
 
@@ -63,10 +66,16 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
                                pg_failed = true;
                                break;
                        }
-                       if (!folio_started && test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) {
-                               trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
-                               folio_start_fscache(folio);
-                               folio_started = true;
+                       if (test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+                               if (!folio_started && test_bit(NETFS_SREQ_COPY_TO_CACHE,
+                                                              &subreq->flags)) {
+                                       trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
+                                       folio_start_private_2(folio);
+                                       folio_started = true;
+                               }
+                       } else {
+                               wback_to_cache |=
+                                       test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
                        }
                        pg_failed |= subreq_failed;
                        sreq_end = subreq->start + subreq->len - 1;
@@ -98,6 +107,11 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
                                kfree(finfo);
                        }
                        folio_mark_uptodate(folio);
+                       if (wback_to_cache && !WARN_ON_ONCE(folio_get_private(folio) != NULL)) {
+                               trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
+                               folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
+                               filemap_dirty_folio(folio->mapping, folio);
+                       }
                }
 
                if (!test_bit(NETFS_RREQ_DONT_UNLOCK_FOLIOS, &rreq->flags)) {
@@ -116,7 +130,9 @@ void netfs_rreq_unlock_folios(struct netfs_io_request *rreq)
 }
 
 static void netfs_cache_expand_readahead(struct netfs_io_request *rreq,
-                                        loff_t *_start, size_t *_len, loff_t i_size)
+                                        unsigned long long *_start,
+                                        unsigned long long *_len,
+                                        unsigned long long i_size)
 {
        struct netfs_cache_resources *cres = &rreq->cache_resources;
 
@@ -266,7 +282,7 @@ int netfs_read_folio(struct file *file, struct folio *folio)
        if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
                goto discard;
 
-       netfs_stat(&netfs_n_rh_readpage);
+       netfs_stat(&netfs_n_rh_read_folio);
        trace_netfs_read(rreq, rreq->start, rreq->len, netfs_read_trace_readpage);
 
        /* Set up the output buffer */
@@ -450,7 +466,7 @@ retry:
        if (!netfs_is_cache_enabled(ctx) &&
            netfs_skip_folio_read(folio, pos, len, false)) {
                netfs_stat(&netfs_n_rh_write_zskip);
-               goto have_folio_no_wait;
+               goto have_folio;
        }
 
        rreq = netfs_alloc_request(mapping, file,
@@ -491,10 +507,6 @@ retry:
        netfs_put_request(rreq, false, netfs_rreq_trace_put_return);
 
 have_folio:
-       ret = folio_wait_fscache_killable(folio);
-       if (ret < 0)
-               goto error;
-have_folio_no_wait:
        *_folio = folio;
        _leave(" = 0");
        return 0;
index 267b622d923b1fc63507300831c3163ba38d8a19..1121601536d1844eddff472160adb61d1982040b 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Network filesystem high-level write support.
+/* Network filesystem high-level buffered write support.
  *
  * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
@@ -26,25 +26,15 @@ enum netfs_how_to_modify {
        NETFS_FLUSH_CONTENT,            /* Flush incompatible content. */
 };
 
-static void netfs_cleanup_buffered_write(struct netfs_io_request *wreq);
-
 static void netfs_set_group(struct folio *folio, struct netfs_group *netfs_group)
 {
-       if (netfs_group && !folio_get_private(folio))
-               folio_attach_private(folio, netfs_get_group(netfs_group));
-}
+       void *priv = folio_get_private(folio);
 
-#if IS_ENABLED(CONFIG_FSCACHE)
-static void netfs_folio_start_fscache(bool caching, struct folio *folio)
-{
-       if (caching)
-               folio_start_fscache(folio);
-}
-#else
-static void netfs_folio_start_fscache(bool caching, struct folio *folio)
-{
+       if (netfs_group && (!priv || priv == NETFS_FOLIO_COPY_TO_CACHE))
+               folio_attach_private(folio, netfs_get_group(netfs_group));
+       else if (!netfs_group && priv == NETFS_FOLIO_COPY_TO_CACHE)
+               folio_detach_private(folio);
 }
-#endif
 
 /*
  * Decide how we should modify a folio.  We might be attempting to do
@@ -63,11 +53,12 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
                                                    bool maybe_trouble)
 {
        struct netfs_folio *finfo = netfs_folio_info(folio);
+       struct netfs_group *group = netfs_folio_group(folio);
        loff_t pos = folio_file_pos(folio);
 
        _enter("");
 
-       if (netfs_folio_group(folio) != netfs_group)
+       if (group != netfs_group && group != NETFS_FOLIO_COPY_TO_CACHE)
                return NETFS_FLUSH_CONTENT;
 
        if (folio_test_uptodate(folio))
@@ -81,16 +72,12 @@ static enum netfs_how_to_modify netfs_how_to_modify(struct netfs_inode *ctx,
 
        if (file->f_mode & FMODE_READ)
                goto no_write_streaming;
-       if (test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
-               goto no_write_streaming;
 
        if (netfs_is_cache_enabled(ctx)) {
                /* We don't want to get a streaming write on a file that loses
                 * caching service temporarily because the backing store got
                 * culled.
                 */
-               if (!test_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags))
-                       set_bit(NETFS_ICTX_NO_WRITE_STREAMING, &ctx->flags);
                goto no_write_streaming;
        }
 
@@ -130,6 +117,37 @@ static struct folio *netfs_grab_folio_for_write(struct address_space *mapping,
                                   mapping_gfp_mask(mapping));
 }
 
+/*
+ * Update i_size and estimate the update to i_blocks to reflect the additional
+ * data written into the pagecache until we can find out from the server what
+ * the values actually are.
+ */
+static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
+                               loff_t i_size, loff_t pos, size_t copied)
+{
+       blkcnt_t add;
+       size_t gap;
+
+       if (ctx->ops->update_i_size) {
+               ctx->ops->update_i_size(inode, pos);
+               return;
+       }
+
+       i_size_write(inode, pos);
+#if IS_ENABLED(CONFIG_FSCACHE)
+       fscache_update_cookie(ctx->cache, NULL, &pos);
+#endif
+
+       gap = SECTOR_SIZE - (i_size & (SECTOR_SIZE - 1));
+       if (copied > gap) {
+               add = DIV_ROUND_UP(copied - gap, SECTOR_SIZE);
+
+               inode->i_blocks = min_t(blkcnt_t,
+                                       DIV_ROUND_UP(pos, SECTOR_SIZE),
+                                       inode->i_blocks + add);
+       }
+}
+
 /**
  * netfs_perform_write - Copy data into the pagecache.
  * @iocb: The operation parameters
@@ -160,7 +178,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
        };
        struct netfs_io_request *wreq = NULL;
        struct netfs_folio *finfo;
-       struct folio *folio;
+       struct folio *folio, *writethrough = NULL;
        enum netfs_how_to_modify howto;
        enum netfs_folio_trace trace;
        unsigned int bdp_flags = (iocb->ki_flags & IOCB_SYNC) ? 0: BDP_ASYNC;
@@ -189,7 +207,9 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
                }
                if (!is_sync_kiocb(iocb))
                        wreq->iocb = iocb;
-               wreq->cleanup = netfs_cleanup_buffered_write;
+               netfs_stat(&netfs_n_wh_writethrough);
+       } else {
+               netfs_stat(&netfs_n_wh_buffered_write);
        }
 
        do {
@@ -230,6 +250,16 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
                offset = pos & (flen - 1);
                part = min_t(size_t, flen - offset, part);
 
+               /* Wait for writeback to complete.  The writeback engine owns
+                * the info in folio->private and may change it until it
+                * removes the WB mark.
+                */
+               if (folio_get_private(folio) &&
+                   folio_wait_writeback_killable(folio)) {
+                       ret = written ? -EINTR : -ERESTARTSYS;
+                       goto error_folio_unlock;
+               }
+
                if (signal_pending(current)) {
                        ret = written ? -EINTR : -ERESTARTSYS;
                        goto error_folio_unlock;
@@ -304,6 +334,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
                                maybe_trouble = true;
                                iov_iter_revert(iter, copied);
                                copied = 0;
+                               folio_unlock(folio);
                                goto retry;
                        }
                        netfs_set_group(folio, netfs_group);
@@ -351,41 +382,22 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
                trace_netfs_folio(folio, trace);
 
                /* Update the inode size if we moved the EOF marker */
-               i_size = i_size_read(inode);
                pos += copied;
-               if (pos > i_size) {
-                       if (ctx->ops->update_i_size) {
-                               ctx->ops->update_i_size(inode, pos);
-                       } else {
-                               i_size_write(inode, pos);
-#if IS_ENABLED(CONFIG_FSCACHE)
-                               fscache_update_cookie(ctx->cache, NULL, &pos);
-#endif
-                       }
-               }
+               i_size = i_size_read(inode);
+               if (pos > i_size)
+                       netfs_update_i_size(ctx, inode, i_size, pos, copied);
                written += copied;
 
                if (likely(!wreq)) {
                        folio_mark_dirty(folio);
+                       folio_unlock(folio);
                } else {
-                       if (folio_test_dirty(folio))
-                               /* Sigh.  mmap. */
-                               folio_clear_dirty_for_io(folio);
-                       /* We make multiple writes to the folio... */
-                       if (!folio_test_writeback(folio)) {
-                               folio_wait_fscache(folio);
-                               folio_start_writeback(folio);
-                               folio_start_fscache(folio);
-                               if (wreq->iter.count == 0)
-                                       trace_netfs_folio(folio, netfs_folio_trace_wthru);
-                               else
-                                       trace_netfs_folio(folio, netfs_folio_trace_wthru_plus);
-                       }
-                       netfs_advance_writethrough(wreq, copied,
-                                                  offset + copied == flen);
+                       netfs_advance_writethrough(wreq, &wbc, folio, copied,
+                                                  offset + copied == flen,
+                                                  &writethrough);
+                       /* Folio unlocked */
                }
        retry:
-               folio_unlock(folio);
                folio_put(folio);
                folio = NULL;
 
@@ -393,8 +405,11 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
        } while (iov_iter_count(iter));
 
 out:
+       if (likely(written) && ctx->ops->post_modify)
+               ctx->ops->post_modify(inode);
+
        if (unlikely(wreq)) {
-               ret2 = netfs_end_writethrough(wreq, iocb);
+               ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
                wbc_detach_inode(&wbc);
                if (ret2 == -EIOCBQUEUED)
                        return ret2;
@@ -505,9 +520,11 @@ EXPORT_SYMBOL(netfs_file_write_iter);
  */
 vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group)
 {
+       struct netfs_group *group;
        struct folio *folio = page_folio(vmf->page);
        struct file *file = vmf->vma->vm_file;
        struct inode *inode = file_inode(file);
+       struct netfs_inode *ictx = netfs_inode(inode);
        vm_fault_t ret = VM_FAULT_RETRY;
        int err;
 
@@ -515,11 +532,13 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
 
        sb_start_pagefault(inode->i_sb);
 
-       if (folio_wait_writeback_killable(folio))
+       if (folio_lock_killable(folio) < 0)
                goto out;
 
-       if (folio_lock_killable(folio) < 0)
+       if (folio_wait_writeback_killable(folio)) {
+               ret = VM_FAULT_LOCKED;
                goto out;
+       }
 
        /* Can we see a streaming write here? */
        if (WARN_ON(!folio_test_uptodate(folio))) {
@@ -527,7 +546,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
                goto out;
        }
 
-       if (netfs_folio_group(folio) != netfs_group) {
+       group = netfs_folio_group(folio);
+       if (group != netfs_group && group != NETFS_FOLIO_COPY_TO_CACHE) {
                folio_unlock(folio);
                err = filemap_fdatawait_range(inode->i_mapping,
                                              folio_pos(folio),
@@ -551,708 +571,11 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
                trace_netfs_folio(folio, netfs_folio_trace_mkwrite);
        netfs_set_group(folio, netfs_group);
        file_update_time(file);
+       if (ictx->ops->post_modify)
+               ictx->ops->post_modify(inode);
        ret = VM_FAULT_LOCKED;
 out:
        sb_end_pagefault(inode->i_sb);
        return ret;
 }
 EXPORT_SYMBOL(netfs_page_mkwrite);
-
-/*
- * Kill all the pages in the given range
- */
-static void netfs_kill_pages(struct address_space *mapping,
-                            loff_t start, loff_t len)
-{
-       struct folio *folio;
-       pgoff_t index = start / PAGE_SIZE;
-       pgoff_t last = (start + len - 1) / PAGE_SIZE, next;
-
-       _enter("%llx-%llx", start, start + len - 1);
-
-       do {
-               _debug("kill %lx (to %lx)", index, last);
-
-               folio = filemap_get_folio(mapping, index);
-               if (IS_ERR(folio)) {
-                       next = index + 1;
-                       continue;
-               }
-
-               next = folio_next_index(folio);
-
-               trace_netfs_folio(folio, netfs_folio_trace_kill);
-               folio_clear_uptodate(folio);
-               if (folio_test_fscache(folio))
-                       folio_end_fscache(folio);
-               folio_end_writeback(folio);
-               folio_lock(folio);
-               generic_error_remove_folio(mapping, folio);
-               folio_unlock(folio);
-               folio_put(folio);
-
-       } while (index = next, index <= last);
-
-       _leave("");
-}
-
-/*
- * Redirty all the pages in a given range.
- */
-static void netfs_redirty_pages(struct address_space *mapping,
-                               loff_t start, loff_t len)
-{
-       struct folio *folio;
-       pgoff_t index = start / PAGE_SIZE;
-       pgoff_t last = (start + len - 1) / PAGE_SIZE, next;
-
-       _enter("%llx-%llx", start, start + len - 1);
-
-       do {
-               _debug("redirty %llx @%llx", len, start);
-
-               folio = filemap_get_folio(mapping, index);
-               if (IS_ERR(folio)) {
-                       next = index + 1;
-                       continue;
-               }
-
-               next = folio_next_index(folio);
-               trace_netfs_folio(folio, netfs_folio_trace_redirty);
-               filemap_dirty_folio(mapping, folio);
-               if (folio_test_fscache(folio))
-                       folio_end_fscache(folio);
-               folio_end_writeback(folio);
-               folio_put(folio);
-       } while (index = next, index <= last);
-
-       balance_dirty_pages_ratelimited(mapping);
-
-       _leave("");
-}
-
-/*
- * Completion of write to server
- */
-static void netfs_pages_written_back(struct netfs_io_request *wreq)
-{
-       struct address_space *mapping = wreq->mapping;
-       struct netfs_folio *finfo;
-       struct netfs_group *group = NULL;
-       struct folio *folio;
-       pgoff_t last;
-       int gcount = 0;
-
-       XA_STATE(xas, &mapping->i_pages, wreq->start / PAGE_SIZE);
-
-       _enter("%llx-%llx", wreq->start, wreq->start + wreq->len);
-
-       rcu_read_lock();
-
-       last = (wreq->start + wreq->len - 1) / PAGE_SIZE;
-       xas_for_each(&xas, folio, last) {
-               WARN(!folio_test_writeback(folio),
-                    "bad %zx @%llx page %lx %lx\n",
-                    wreq->len, wreq->start, folio->index, last);
-
-               if ((finfo = netfs_folio_info(folio))) {
-                       /* Streaming writes cannot be redirtied whilst under
-                        * writeback, so discard the streaming record.
-                        */
-                       folio_detach_private(folio);
-                       group = finfo->netfs_group;
-                       gcount++;
-                       trace_netfs_folio(folio, netfs_folio_trace_clear_s);
-                       kfree(finfo);
-               } else if ((group = netfs_folio_group(folio))) {
-                       /* Need to detach the group pointer if the page didn't
-                        * get redirtied.  If it has been redirtied, then it
-                        * must be within the same group.
-                        */
-                       if (folio_test_dirty(folio)) {
-                               trace_netfs_folio(folio, netfs_folio_trace_redirtied);
-                               goto end_wb;
-                       }
-                       if (folio_trylock(folio)) {
-                               if (!folio_test_dirty(folio)) {
-                                       folio_detach_private(folio);
-                                       gcount++;
-                                       trace_netfs_folio(folio, netfs_folio_trace_clear_g);
-                               } else {
-                                       trace_netfs_folio(folio, netfs_folio_trace_redirtied);
-                               }
-                               folio_unlock(folio);
-                               goto end_wb;
-                       }
-
-                       xas_pause(&xas);
-                       rcu_read_unlock();
-                       folio_lock(folio);
-                       if (!folio_test_dirty(folio)) {
-                               folio_detach_private(folio);
-                               gcount++;
-                               trace_netfs_folio(folio, netfs_folio_trace_clear_g);
-                       } else {
-                               trace_netfs_folio(folio, netfs_folio_trace_redirtied);
-                       }
-                       folio_unlock(folio);
-                       rcu_read_lock();
-               } else {
-                       trace_netfs_folio(folio, netfs_folio_trace_clear);
-               }
-       end_wb:
-               if (folio_test_fscache(folio))
-                       folio_end_fscache(folio);
-               xas_advance(&xas, folio_next_index(folio) - 1);
-               folio_end_writeback(folio);
-       }
-
-       rcu_read_unlock();
-       netfs_put_group_many(group, gcount);
-       _leave("");
-}
-
-/*
- * Deal with the disposition of the folios that are under writeback to close
- * out the operation.
- */
-static void netfs_cleanup_buffered_write(struct netfs_io_request *wreq)
-{
-       struct address_space *mapping = wreq->mapping;
-
-       _enter("");
-
-       switch (wreq->error) {
-       case 0:
-               netfs_pages_written_back(wreq);
-               break;
-
-       default:
-               pr_notice("R=%08x Unexpected error %d\n", wreq->debug_id, wreq->error);
-               fallthrough;
-       case -EACCES:
-       case -EPERM:
-       case -ENOKEY:
-       case -EKEYEXPIRED:
-       case -EKEYREJECTED:
-       case -EKEYREVOKED:
-       case -ENETRESET:
-       case -EDQUOT:
-       case -ENOSPC:
-               netfs_redirty_pages(mapping, wreq->start, wreq->len);
-               break;
-
-       case -EROFS:
-       case -EIO:
-       case -EREMOTEIO:
-       case -EFBIG:
-       case -ENOENT:
-       case -ENOMEDIUM:
-       case -ENXIO:
-               netfs_kill_pages(mapping, wreq->start, wreq->len);
-               break;
-       }
-
-       if (wreq->error)
-               mapping_set_error(mapping, wreq->error);
-       if (wreq->netfs_ops->done)
-               wreq->netfs_ops->done(wreq);
-}
-
-/*
- * Extend the region to be written back to include subsequent contiguously
- * dirty pages if possible, but don't sleep while doing so.
- *
- * If this page holds new content, then we can include filler zeros in the
- * writeback.
- */
-static void netfs_extend_writeback(struct address_space *mapping,
-                                  struct netfs_group *group,
-                                  struct xa_state *xas,
-                                  long *_count,
-                                  loff_t start,
-                                  loff_t max_len,
-                                  bool caching,
-                                  size_t *_len,
-                                  size_t *_top)
-{
-       struct netfs_folio *finfo;
-       struct folio_batch fbatch;
-       struct folio *folio;
-       unsigned int i;
-       pgoff_t index = (start + *_len) / PAGE_SIZE;
-       size_t len;
-       void *priv;
-       bool stop = true;
-
-       folio_batch_init(&fbatch);
-
-       do {
-               /* Firstly, we gather up a batch of contiguous dirty pages
-                * under the RCU read lock - but we can't clear the dirty flags
-                * there if any of those pages are mapped.
-                */
-               rcu_read_lock();
-
-               xas_for_each(xas, folio, ULONG_MAX) {
-                       stop = true;
-                       if (xas_retry(xas, folio))
-                               continue;
-                       if (xa_is_value(folio))
-                               break;
-                       if (folio->index != index) {
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       if (!folio_try_get_rcu(folio)) {
-                               xas_reset(xas);
-                               continue;
-                       }
-
-                       /* Has the folio moved or been split? */
-                       if (unlikely(folio != xas_reload(xas))) {
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       if (!folio_trylock(folio)) {
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-                       if (!folio_test_dirty(folio) ||
-                           folio_test_writeback(folio) ||
-                           folio_test_fscache(folio)) {
-                               folio_unlock(folio);
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       stop = false;
-                       len = folio_size(folio);
-                       priv = folio_get_private(folio);
-                       if ((const struct netfs_group *)priv != group) {
-                               stop = true;
-                               finfo = netfs_folio_info(folio);
-                               if (finfo->netfs_group != group ||
-                                   finfo->dirty_offset > 0) {
-                                       folio_unlock(folio);
-                                       folio_put(folio);
-                                       xas_reset(xas);
-                                       break;
-                               }
-                               len = finfo->dirty_len;
-                       }
-
-                       *_top += folio_size(folio);
-                       index += folio_nr_pages(folio);
-                       *_count -= folio_nr_pages(folio);
-                       *_len += len;
-                       if (*_len >= max_len || *_count <= 0)
-                               stop = true;
-
-                       if (!folio_batch_add(&fbatch, folio))
-                               break;
-                       if (stop)
-                               break;
-               }
-
-               xas_pause(xas);
-               rcu_read_unlock();
-
-               /* Now, if we obtained any folios, we can shift them to being
-                * writable and mark them for caching.
-                */
-               if (!folio_batch_count(&fbatch))
-                       break;
-
-               for (i = 0; i < folio_batch_count(&fbatch); i++) {
-                       folio = fbatch.folios[i];
-                       trace_netfs_folio(folio, netfs_folio_trace_store_plus);
-
-                       if (!folio_clear_dirty_for_io(folio))
-                               BUG();
-                       folio_start_writeback(folio);
-                       netfs_folio_start_fscache(caching, folio);
-                       folio_unlock(folio);
-               }
-
-               folio_batch_release(&fbatch);
-               cond_resched();
-       } while (!stop);
-}
-
-/*
- * Synchronously write back the locked page and any subsequent non-locked dirty
- * pages.
- */
-static ssize_t netfs_write_back_from_locked_folio(struct address_space *mapping,
-                                                 struct writeback_control *wbc,
-                                                 struct netfs_group *group,
-                                                 struct xa_state *xas,
-                                                 struct folio *folio,
-                                                 unsigned long long start,
-                                                 unsigned long long end)
-{
-       struct netfs_io_request *wreq;
-       struct netfs_folio *finfo;
-       struct netfs_inode *ctx = netfs_inode(mapping->host);
-       unsigned long long i_size = i_size_read(&ctx->inode);
-       size_t len, max_len;
-       bool caching = netfs_is_cache_enabled(ctx);
-       long count = wbc->nr_to_write;
-       int ret;
-
-       _enter(",%lx,%llx-%llx,%u", folio->index, start, end, caching);
-
-       wreq = netfs_alloc_request(mapping, NULL, start, folio_size(folio),
-                                  NETFS_WRITEBACK);
-       if (IS_ERR(wreq)) {
-               folio_unlock(folio);
-               return PTR_ERR(wreq);
-       }
-
-       if (!folio_clear_dirty_for_io(folio))
-               BUG();
-       folio_start_writeback(folio);
-       netfs_folio_start_fscache(caching, folio);
-
-       count -= folio_nr_pages(folio);
-
-       /* Find all consecutive lockable dirty pages that have contiguous
-        * written regions, stopping when we find a page that is not
-        * immediately lockable, is not dirty or is missing, or we reach the
-        * end of the range.
-        */
-       trace_netfs_folio(folio, netfs_folio_trace_store);
-
-       len = wreq->len;
-       finfo = netfs_folio_info(folio);
-       if (finfo) {
-               start += finfo->dirty_offset;
-               if (finfo->dirty_offset + finfo->dirty_len != len) {
-                       len = finfo->dirty_len;
-                       goto cant_expand;
-               }
-               len = finfo->dirty_len;
-       }
-
-       if (start < i_size) {
-               /* Trim the write to the EOF; the extra data is ignored.  Also
-                * put an upper limit on the size of a single storedata op.
-                */
-               max_len = 65536 * 4096;
-               max_len = min_t(unsigned long long, max_len, end - start + 1);
-               max_len = min_t(unsigned long long, max_len, i_size - start);
-
-               if (len < max_len)
-                       netfs_extend_writeback(mapping, group, xas, &count, start,
-                                              max_len, caching, &len, &wreq->upper_len);
-       }
-
-cant_expand:
-       len = min_t(unsigned long long, len, i_size - start);
-
-       /* We now have a contiguous set of dirty pages, each with writeback
-        * set; the first page is still locked at this point, but all the rest
-        * have been unlocked.
-        */
-       folio_unlock(folio);
-       wreq->start = start;
-       wreq->len = len;
-
-       if (start < i_size) {
-               _debug("write back %zx @%llx [%llx]", len, start, i_size);
-
-               /* Speculatively write to the cache.  We have to fix this up
-                * later if the store fails.
-                */
-               wreq->cleanup = netfs_cleanup_buffered_write;
-
-               iov_iter_xarray(&wreq->iter, ITER_SOURCE, &mapping->i_pages, start,
-                               wreq->upper_len);
-               __set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags);
-               ret = netfs_begin_write(wreq, true, netfs_write_trace_writeback);
-               if (ret == 0 || ret == -EIOCBQUEUED)
-                       wbc->nr_to_write -= len / PAGE_SIZE;
-       } else {
-               _debug("write discard %zx @%llx [%llx]", len, start, i_size);
-
-               /* The dirty region was entirely beyond the EOF. */
-               fscache_clear_page_bits(mapping, start, len, caching);
-               netfs_pages_written_back(wreq);
-               ret = 0;
-       }
-
-       netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
-       _leave(" = 1");
-       return 1;
-}
-
-/*
- * Write a region of pages back to the server
- */
-static ssize_t netfs_writepages_begin(struct address_space *mapping,
-                                     struct writeback_control *wbc,
-                                     struct netfs_group *group,
-                                     struct xa_state *xas,
-                                     unsigned long long *_start,
-                                     unsigned long long end)
-{
-       const struct netfs_folio *finfo;
-       struct folio *folio;
-       unsigned long long start = *_start;
-       ssize_t ret;
-       void *priv;
-       int skips = 0;
-
-       _enter("%llx,%llx,", start, end);
-
-search_again:
-       /* Find the first dirty page in the group. */
-       rcu_read_lock();
-
-       for (;;) {
-               folio = xas_find_marked(xas, end / PAGE_SIZE, PAGECACHE_TAG_DIRTY);
-               if (xas_retry(xas, folio) || xa_is_value(folio))
-                       continue;
-               if (!folio)
-                       break;
-
-               if (!folio_try_get_rcu(folio)) {
-                       xas_reset(xas);
-                       continue;
-               }
-
-               if (unlikely(folio != xas_reload(xas))) {
-                       folio_put(folio);
-                       xas_reset(xas);
-                       continue;
-               }
-
-               /* Skip any dirty folio that's not in the group of interest. */
-               priv = folio_get_private(folio);
-               if ((const struct netfs_group *)priv != group) {
-                       finfo = netfs_folio_info(folio);
-                       if (finfo->netfs_group != group) {
-                               folio_put(folio);
-                               continue;
-                       }
-               }
-
-               xas_pause(xas);
-               break;
-       }
-       rcu_read_unlock();
-       if (!folio)
-               return 0;
-
-       start = folio_pos(folio); /* May regress with THPs */
-
-       _debug("wback %lx", folio->index);
-
-       /* At this point we hold neither the i_pages lock nor the page lock:
-        * the page may be truncated or invalidated (changing page->mapping to
-        * NULL), or even swizzled back from swapper_space to tmpfs file
-        * mapping
-        */
-lock_again:
-       if (wbc->sync_mode != WB_SYNC_NONE) {
-               ret = folio_lock_killable(folio);
-               if (ret < 0)
-                       return ret;
-       } else {
-               if (!folio_trylock(folio))
-                       goto search_again;
-       }
-
-       if (folio->mapping != mapping ||
-           !folio_test_dirty(folio)) {
-               start += folio_size(folio);
-               folio_unlock(folio);
-               goto search_again;
-       }
-
-       if (folio_test_writeback(folio) ||
-           folio_test_fscache(folio)) {
-               folio_unlock(folio);
-               if (wbc->sync_mode != WB_SYNC_NONE) {
-                       folio_wait_writeback(folio);
-#ifdef CONFIG_FSCACHE
-                       folio_wait_fscache(folio);
-#endif
-                       goto lock_again;
-               }
-
-               start += folio_size(folio);
-               if (wbc->sync_mode == WB_SYNC_NONE) {
-                       if (skips >= 5 || need_resched()) {
-                               ret = 0;
-                               goto out;
-                       }
-                       skips++;
-               }
-               goto search_again;
-       }
-
-       ret = netfs_write_back_from_locked_folio(mapping, wbc, group, xas,
-                                                folio, start, end);
-out:
-       if (ret > 0)
-               *_start = start + ret;
-       _leave(" = %zd [%llx]", ret, *_start);
-       return ret;
-}
-
-/*
- * Write a region of pages back to the server
- */
-static int netfs_writepages_region(struct address_space *mapping,
-                                  struct writeback_control *wbc,
-                                  struct netfs_group *group,
-                                  unsigned long long *_start,
-                                  unsigned long long end)
-{
-       ssize_t ret;
-
-       XA_STATE(xas, &mapping->i_pages, *_start / PAGE_SIZE);
-
-       do {
-               ret = netfs_writepages_begin(mapping, wbc, group, &xas,
-                                            _start, end);
-               if (ret > 0 && wbc->nr_to_write > 0)
-                       cond_resched();
-       } while (ret > 0 && wbc->nr_to_write > 0);
-
-       return ret > 0 ? 0 : ret;
-}
-
-/*
- * write some of the pending data back to the server
- */
-int netfs_writepages(struct address_space *mapping,
-                    struct writeback_control *wbc)
-{
-       struct netfs_group *group = NULL;
-       loff_t start, end;
-       int ret;
-
-       _enter("");
-
-       /* We have to be careful as we can end up racing with setattr()
-        * truncating the pagecache since the caller doesn't take a lock here
-        * to prevent it.
-        */
-
-       if (wbc->range_cyclic && mapping->writeback_index) {
-               start = mapping->writeback_index * PAGE_SIZE;
-               ret = netfs_writepages_region(mapping, wbc, group,
-                                             &start, LLONG_MAX);
-               if (ret < 0)
-                       goto out;
-
-               if (wbc->nr_to_write <= 0) {
-                       mapping->writeback_index = start / PAGE_SIZE;
-                       goto out;
-               }
-
-               start = 0;
-               end = mapping->writeback_index * PAGE_SIZE;
-               mapping->writeback_index = 0;
-               ret = netfs_writepages_region(mapping, wbc, group, &start, end);
-               if (ret == 0)
-                       mapping->writeback_index = start / PAGE_SIZE;
-       } else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) {
-               start = 0;
-               ret = netfs_writepages_region(mapping, wbc, group,
-                                             &start, LLONG_MAX);
-               if (wbc->nr_to_write > 0 && ret == 0)
-                       mapping->writeback_index = start / PAGE_SIZE;
-       } else {
-               start = wbc->range_start;
-               ret = netfs_writepages_region(mapping, wbc, group,
-                                             &start, wbc->range_end);
-       }
-
-out:
-       _leave(" = %d", ret);
-       return ret;
-}
-EXPORT_SYMBOL(netfs_writepages);
-
-/*
- * Deal with the disposition of a laundered folio.
- */
-static void netfs_cleanup_launder_folio(struct netfs_io_request *wreq)
-{
-       if (wreq->error) {
-               pr_notice("R=%08x Laundering error %d\n", wreq->debug_id, wreq->error);
-               mapping_set_error(wreq->mapping, wreq->error);
-       }
-}
-
-/**
- * netfs_launder_folio - Clean up a dirty folio that's being invalidated
- * @folio: The folio to clean
- *
- * This is called to write back a folio that's being invalidated when an inode
- * is getting torn down.  Ideally, writepages would be used instead.
- */
-int netfs_launder_folio(struct folio *folio)
-{
-       struct netfs_io_request *wreq;
-       struct address_space *mapping = folio->mapping;
-       struct netfs_folio *finfo = netfs_folio_info(folio);
-       struct netfs_group *group = netfs_folio_group(folio);
-       struct bio_vec bvec;
-       unsigned long long i_size = i_size_read(mapping->host);
-       unsigned long long start = folio_pos(folio);
-       size_t offset = 0, len;
-       int ret = 0;
-
-       if (finfo) {
-               offset = finfo->dirty_offset;
-               start += offset;
-               len = finfo->dirty_len;
-       } else {
-               len = folio_size(folio);
-       }
-       len = min_t(unsigned long long, len, i_size - start);
-
-       wreq = netfs_alloc_request(mapping, NULL, start, len, NETFS_LAUNDER_WRITE);
-       if (IS_ERR(wreq)) {
-               ret = PTR_ERR(wreq);
-               goto out;
-       }
-
-       if (!folio_clear_dirty_for_io(folio))
-               goto out_put;
-
-       trace_netfs_folio(folio, netfs_folio_trace_launder);
-
-       _debug("launder %llx-%llx", start, start + len - 1);
-
-       /* Speculatively write to the cache.  We have to fix this up later if
-        * the store fails.
-        */
-       wreq->cleanup = netfs_cleanup_launder_folio;
-
-       bvec_set_folio(&bvec, folio, len, offset);
-       iov_iter_bvec(&wreq->iter, ITER_SOURCE, &bvec, 1, len);
-       __set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags);
-       ret = netfs_begin_write(wreq, true, netfs_write_trace_launder);
-
-out_put:
-       folio_detach_private(folio);
-       netfs_put_group(group);
-       kfree(finfo);
-       netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
-out:
-       folio_wait_fscache(folio);
-       _leave(" = %d", ret);
-       return ret;
-}
-EXPORT_SYMBOL(netfs_launder_folio);
index ad4370b3935d6ee1678e82f05926b990f05edc1d..10a1e4da6bda5c59c66199f8473825f97a46bcff 100644 (file)
@@ -26,7 +26,7 @@
  *
  * The caller must hold any appropriate locks.
  */
-static ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter)
+ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter)
 {
        struct netfs_io_request *rreq;
        ssize_t ret;
@@ -98,6 +98,7 @@ out:
                iov_iter_revert(iter, orig_count - iov_iter_count(iter));
        return ret;
 }
+EXPORT_SYMBOL(netfs_unbuffered_read_iter_locked);
 
 /**
  * netfs_unbuffered_read_iter - Perform an unbuffered or direct I/O read
index bee047e20f5d6933e3af452eb150e4eb2e97d941..608ba6416919a8f95fd06645980964ba40bd4308 100644 (file)
@@ -34,6 +34,7 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
        unsigned long long start = iocb->ki_pos;
        unsigned long long end = start + iov_iter_count(iter);
        ssize_t ret, n;
+       size_t len = iov_iter_count(iter);
        bool async = !is_sync_kiocb(iocb);
 
        _enter("");
@@ -46,13 +47,17 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
 
        _debug("uw %llx-%llx", start, end);
 
-       wreq = netfs_alloc_request(iocb->ki_filp->f_mapping, iocb->ki_filp,
-                                  start, end - start,
-                                  iocb->ki_flags & IOCB_DIRECT ?
-                                  NETFS_DIO_WRITE : NETFS_UNBUFFERED_WRITE);
+       wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp, start,
+                                     iocb->ki_flags & IOCB_DIRECT ?
+                                     NETFS_DIO_WRITE : NETFS_UNBUFFERED_WRITE);
        if (IS_ERR(wreq))
                return PTR_ERR(wreq);
 
+       wreq->io_streams[0].avail = true;
+       trace_netfs_write(wreq, (iocb->ki_flags & IOCB_DIRECT ?
+                                netfs_write_trace_dio_write :
+                                netfs_write_trace_unbuffered_write));
+
        {
                /* If this is an async op and we're not using a bounce buffer,
                 * we have to save the source buffer as the iterator is only
@@ -63,7 +68,7 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
                 * request.
                 */
                if (async || user_backed_iter(iter)) {
-                       n = netfs_extract_user_iter(iter, wreq->len, &wreq->iter, 0);
+                       n = netfs_extract_user_iter(iter, len, &wreq->iter, 0);
                        if (n < 0) {
                                ret = n;
                                goto out;
@@ -71,7 +76,6 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
                        wreq->direct_bv = (struct bio_vec *)wreq->iter.bvec;
                        wreq->direct_bv_count = n;
                        wreq->direct_bv_unpin = iov_iter_extract_will_pin(iter);
-                       wreq->len = iov_iter_count(&wreq->iter);
                } else {
                        wreq->iter = *iter;
                }
@@ -79,6 +83,8 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
                wreq->io_iter = wreq->iter;
        }
 
+       __set_bit(NETFS_RREQ_USE_IO_ITER, &wreq->flags);
+
        /* Copy the data into the bounce buffer and encrypt it. */
        // TODO
 
@@ -87,10 +93,7 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
        if (async)
                wreq->iocb = iocb;
        wreq->cleanup = netfs_cleanup_dio_write;
-       ret = netfs_begin_write(wreq, is_sync_kiocb(iocb),
-                               iocb->ki_flags & IOCB_DIRECT ?
-                               netfs_write_trace_dio_write :
-                               netfs_write_trace_unbuffered_write);
+       ret = netfs_unbuffered_write(wreq, is_sync_kiocb(iocb), iov_iter_count(&wreq->io_iter));
        if (ret < 0) {
                _debug("begin = %zd", ret);
                goto out;
@@ -100,9 +103,8 @@ static ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov
                trace_netfs_rreq(wreq, netfs_rreq_trace_wait_ip);
                wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS,
                            TASK_UNINTERRUPTIBLE);
-
+               smp_rmb(); /* Read error/transferred after RIP flag */
                ret = wreq->error;
-               _debug("waited = %zd", ret);
                if (ret == 0) {
                        ret = wreq->transferred;
                        iocb->ki_pos += ret;
@@ -132,18 +134,20 @@ out:
 ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
        struct file *file = iocb->ki_filp;
-       struct inode *inode = file->f_mapping->host;
+       struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
        struct netfs_inode *ictx = netfs_inode(inode);
-       unsigned long long end;
        ssize_t ret;
+       loff_t pos = iocb->ki_pos;
+       unsigned long long end = pos + iov_iter_count(from) - 1;
 
-       _enter("%llx,%zx,%llx", iocb->ki_pos, iov_iter_count(from), i_size_read(inode));
+       _enter("%llx,%zx,%llx", pos, iov_iter_count(from), i_size_read(inode));
 
        if (!iov_iter_count(from))
                return 0;
 
        trace_netfs_write_iter(iocb, from);
-       netfs_stat(&netfs_n_rh_dio_write);
+       netfs_stat(&netfs_n_wh_dio_write);
 
        ret = netfs_start_io_direct(inode);
        if (ret < 0)
@@ -157,7 +161,25 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
        ret = file_update_time(file);
        if (ret < 0)
                goto out;
-       ret = kiocb_invalidate_pages(iocb, iov_iter_count(from));
+       if (iocb->ki_flags & IOCB_NOWAIT) {
+               /* We could block if there are any pages in the range. */
+               ret = -EAGAIN;
+               if (filemap_range_has_page(mapping, pos, end))
+                       if (filemap_invalidate_inode(inode, true, pos, end))
+                               goto out;
+       } else {
+               ret = filemap_write_and_wait_range(mapping, pos, end);
+               if (ret < 0)
+                       goto out;
+       }
+
+       /*
+        * After a write we want buffered reads to be sure to go to disk to get
+        * the new data.  We invalidate clean cached page from the region we're
+        * about to write.  We do this *before* the write so that we can return
+        * without clobbering -EIOCBQUEUED from ->direct_IO().
+        */
+       ret = filemap_invalidate_inode(inode, true, pos, end);
        if (ret < 0)
                goto out;
        end = iocb->ki_pos + iov_iter_count(from);
index 43a651ed826413d8ea60dcb240950e2a074aca28..38637e5c9b57763ebaa30c793c0ebe244fa9ae34 100644 (file)
@@ -166,6 +166,7 @@ struct fscache_write_request {
        loff_t                  start;
        size_t                  len;
        bool                    set_bits;
+       bool                    using_pgpriv2;
        netfs_io_terminated_t   term_func;
        void                    *term_func_priv;
 };
@@ -182,7 +183,7 @@ void __fscache_clear_page_bits(struct address_space *mapping,
 
                rcu_read_lock();
                xas_for_each(&xas, page, last) {
-                       end_page_fscache(page);
+                       folio_end_private_2(page_folio(page));
                }
                rcu_read_unlock();
        }
@@ -197,8 +198,9 @@ static void fscache_wreq_done(void *priv, ssize_t transferred_or_error,
 {
        struct fscache_write_request *wreq = priv;
 
-       fscache_clear_page_bits(wreq->mapping, wreq->start, wreq->len,
-                               wreq->set_bits);
+       if (wreq->using_pgpriv2)
+               fscache_clear_page_bits(wreq->mapping, wreq->start, wreq->len,
+                                       wreq->set_bits);
 
        if (wreq->term_func)
                wreq->term_func(wreq->term_func_priv, transferred_or_error,
@@ -212,7 +214,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
                              loff_t start, size_t len, loff_t i_size,
                              netfs_io_terminated_t term_func,
                              void *term_func_priv,
-                             bool cond)
+                             bool using_pgpriv2, bool cond)
 {
        struct fscache_write_request *wreq;
        struct netfs_cache_resources *cres;
@@ -230,6 +232,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie,
        wreq->mapping           = mapping;
        wreq->start             = start;
        wreq->len               = len;
+       wreq->using_pgpriv2     = using_pgpriv2;
        wreq->set_bits          = cond;
        wreq->term_func         = term_func;
        wreq->term_func_priv    = term_func_priv;
@@ -257,7 +260,8 @@ abandon_end:
 abandon_free:
        kfree(wreq);
 abandon:
-       fscache_clear_page_bits(mapping, start, len, cond);
+       if (using_pgpriv2)
+               fscache_clear_page_bits(mapping, start, len, cond);
        if (term_func)
                term_func(term_func_priv, ret, false);
 }
index ec7045d24400df09bd5a933401a7fbb2d36a3d24..95e281a8af7886fac53851b591d41592929cf444 100644 (file)
@@ -37,6 +37,8 @@ int netfs_begin_read(struct netfs_io_request *rreq, bool sync);
 extern unsigned int netfs_debug;
 extern struct list_head netfs_io_requests;
 extern spinlock_t netfs_proc_lock;
+extern mempool_t netfs_request_pool;
+extern mempool_t netfs_subrequest_pool;
 
 #ifdef CONFIG_PROC_FS
 static inline void netfs_proc_add_rreq(struct netfs_io_request *rreq)
@@ -90,23 +92,13 @@ static inline void netfs_see_request(struct netfs_io_request *rreq,
        trace_netfs_rreq_ref(rreq->debug_id, refcount_read(&rreq->ref), what);
 }
 
-/*
- * output.c
- */
-int netfs_begin_write(struct netfs_io_request *wreq, bool may_wait,
-                     enum netfs_write_trace what);
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len);
-int netfs_advance_writethrough(struct netfs_io_request *wreq, size_t copied, bool to_page_end);
-int netfs_end_writethrough(struct netfs_io_request *wreq, struct kiocb *iocb);
-
 /*
  * stats.c
  */
 #ifdef CONFIG_NETFS_STATS
 extern atomic_t netfs_n_rh_dio_read;
-extern atomic_t netfs_n_rh_dio_write;
 extern atomic_t netfs_n_rh_readahead;
-extern atomic_t netfs_n_rh_readpage;
+extern atomic_t netfs_n_rh_read_folio;
 extern atomic_t netfs_n_rh_rreq;
 extern atomic_t netfs_n_rh_sreq;
 extern atomic_t netfs_n_rh_download;
@@ -123,6 +115,10 @@ extern atomic_t netfs_n_rh_write_begin;
 extern atomic_t netfs_n_rh_write_done;
 extern atomic_t netfs_n_rh_write_failed;
 extern atomic_t netfs_n_rh_write_zskip;
+extern atomic_t netfs_n_wh_buffered_write;
+extern atomic_t netfs_n_wh_writethrough;
+extern atomic_t netfs_n_wh_dio_write;
+extern atomic_t netfs_n_wh_writepages;
 extern atomic_t netfs_n_wh_wstream_conflict;
 extern atomic_t netfs_n_wh_upload;
 extern atomic_t netfs_n_wh_upload_done;
@@ -148,6 +144,33 @@ static inline void netfs_stat_d(atomic_t *stat)
 #define netfs_stat_d(x) do {} while(0)
 #endif
 
+/*
+ * write_collect.c
+ */
+int netfs_folio_written_back(struct folio *folio);
+void netfs_write_collection_worker(struct work_struct *work);
+void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async);
+
+/*
+ * write_issue.c
+ */
+struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
+                                               struct file *file,
+                                               loff_t start,
+                                               enum netfs_io_origin origin);
+void netfs_reissue_write(struct netfs_io_stream *stream,
+                        struct netfs_io_subrequest *subreq);
+int netfs_advance_write(struct netfs_io_request *wreq,
+                       struct netfs_io_stream *stream,
+                       loff_t start, size_t len, bool to_eof);
+struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len);
+int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+                              struct folio *folio, size_t copied, bool to_page_end,
+                              struct folio **writethrough_cache);
+int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+                          struct folio *writethrough_cache);
+int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t len);
+
 /*
  * Miscellaneous functions.
  */
@@ -168,7 +191,7 @@ static inline bool netfs_is_cache_enabled(struct netfs_inode *ctx)
  */
 static inline struct netfs_group *netfs_get_group(struct netfs_group *netfs_group)
 {
-       if (netfs_group)
+       if (netfs_group && netfs_group != NETFS_FOLIO_COPY_TO_CACHE)
                refcount_inc(&netfs_group->ref);
        return netfs_group;
 }
@@ -178,7 +201,9 @@ static inline struct netfs_group *netfs_get_group(struct netfs_group *netfs_grou
  */
 static inline void netfs_put_group(struct netfs_group *netfs_group)
 {
-       if (netfs_group && refcount_dec_and_test(&netfs_group->ref))
+       if (netfs_group &&
+           netfs_group != NETFS_FOLIO_COPY_TO_CACHE &&
+           refcount_dec_and_test(&netfs_group->ref))
                netfs_group->free(netfs_group);
 }
 
@@ -187,7 +212,9 @@ static inline void netfs_put_group(struct netfs_group *netfs_group)
  */
 static inline void netfs_put_group_many(struct netfs_group *netfs_group, int nr)
 {
-       if (netfs_group && refcount_sub_and_test(nr, &netfs_group->ref))
+       if (netfs_group &&
+           netfs_group != NETFS_FOLIO_COPY_TO_CACHE &&
+           refcount_sub_and_test(nr, &netfs_group->ref))
                netfs_group->free(netfs_group);
 }
 
index 4261ad6c55b664a7e3da006d007de03664790641..c93851b9836889e87257cd058eec8926201738b2 100644 (file)
@@ -98,145 +98,6 @@ static void netfs_rreq_completed(struct netfs_io_request *rreq, bool was_async)
        netfs_put_request(rreq, was_async, netfs_rreq_trace_put_complete);
 }
 
-/*
- * Deal with the completion of writing the data to the cache.  We have to clear
- * the PG_fscache bits on the folios involved and release the caller's ref.
- *
- * May be called in softirq mode and we inherit a ref from the caller.
- */
-static void netfs_rreq_unmark_after_write(struct netfs_io_request *rreq,
-                                         bool was_async)
-{
-       struct netfs_io_subrequest *subreq;
-       struct folio *folio;
-       pgoff_t unlocked = 0;
-       bool have_unlocked = false;
-
-       rcu_read_lock();
-
-       list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
-               XA_STATE(xas, &rreq->mapping->i_pages, subreq->start / PAGE_SIZE);
-
-               xas_for_each(&xas, folio, (subreq->start + subreq->len - 1) / PAGE_SIZE) {
-                       if (xas_retry(&xas, folio))
-                               continue;
-
-                       /* We might have multiple writes from the same huge
-                        * folio, but we mustn't unlock a folio more than once.
-                        */
-                       if (have_unlocked && folio->index <= unlocked)
-                               continue;
-                       unlocked = folio_next_index(folio) - 1;
-                       trace_netfs_folio(folio, netfs_folio_trace_end_copy);
-                       folio_end_fscache(folio);
-                       have_unlocked = true;
-               }
-       }
-
-       rcu_read_unlock();
-       netfs_rreq_completed(rreq, was_async);
-}
-
-static void netfs_rreq_copy_terminated(void *priv, ssize_t transferred_or_error,
-                                      bool was_async)
-{
-       struct netfs_io_subrequest *subreq = priv;
-       struct netfs_io_request *rreq = subreq->rreq;
-
-       if (IS_ERR_VALUE(transferred_or_error)) {
-               netfs_stat(&netfs_n_rh_write_failed);
-               trace_netfs_failure(rreq, subreq, transferred_or_error,
-                                   netfs_fail_copy_to_cache);
-       } else {
-               netfs_stat(&netfs_n_rh_write_done);
-       }
-
-       trace_netfs_sreq(subreq, netfs_sreq_trace_write_term);
-
-       /* If we decrement nr_copy_ops to 0, the ref belongs to us. */
-       if (atomic_dec_and_test(&rreq->nr_copy_ops))
-               netfs_rreq_unmark_after_write(rreq, was_async);
-
-       netfs_put_subrequest(subreq, was_async, netfs_sreq_trace_put_terminated);
-}
-
-/*
- * Perform any outstanding writes to the cache.  We inherit a ref from the
- * caller.
- */
-static void netfs_rreq_do_write_to_cache(struct netfs_io_request *rreq)
-{
-       struct netfs_cache_resources *cres = &rreq->cache_resources;
-       struct netfs_io_subrequest *subreq, *next, *p;
-       struct iov_iter iter;
-       int ret;
-
-       trace_netfs_rreq(rreq, netfs_rreq_trace_copy);
-
-       /* We don't want terminating writes trying to wake us up whilst we're
-        * still going through the list.
-        */
-       atomic_inc(&rreq->nr_copy_ops);
-
-       list_for_each_entry_safe(subreq, p, &rreq->subrequests, rreq_link) {
-               if (!test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) {
-                       list_del_init(&subreq->rreq_link);
-                       netfs_put_subrequest(subreq, false,
-                                            netfs_sreq_trace_put_no_copy);
-               }
-       }
-
-       list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
-               /* Amalgamate adjacent writes */
-               while (!list_is_last(&subreq->rreq_link, &rreq->subrequests)) {
-                       next = list_next_entry(subreq, rreq_link);
-                       if (next->start != subreq->start + subreq->len)
-                               break;
-                       subreq->len += next->len;
-                       list_del_init(&next->rreq_link);
-                       netfs_put_subrequest(next, false,
-                                            netfs_sreq_trace_put_merged);
-               }
-
-               ret = cres->ops->prepare_write(cres, &subreq->start, &subreq->len,
-                                              subreq->len, rreq->i_size, true);
-               if (ret < 0) {
-                       trace_netfs_failure(rreq, subreq, ret, netfs_fail_prepare_write);
-                       trace_netfs_sreq(subreq, netfs_sreq_trace_write_skip);
-                       continue;
-               }
-
-               iov_iter_xarray(&iter, ITER_SOURCE, &rreq->mapping->i_pages,
-                               subreq->start, subreq->len);
-
-               atomic_inc(&rreq->nr_copy_ops);
-               netfs_stat(&netfs_n_rh_write);
-               netfs_get_subrequest(subreq, netfs_sreq_trace_get_copy_to_cache);
-               trace_netfs_sreq(subreq, netfs_sreq_trace_write);
-               cres->ops->write(cres, subreq->start, &iter,
-                                netfs_rreq_copy_terminated, subreq);
-       }
-
-       /* If we decrement nr_copy_ops to 0, the usage ref belongs to us. */
-       if (atomic_dec_and_test(&rreq->nr_copy_ops))
-               netfs_rreq_unmark_after_write(rreq, false);
-}
-
-static void netfs_rreq_write_to_cache_work(struct work_struct *work)
-{
-       struct netfs_io_request *rreq =
-               container_of(work, struct netfs_io_request, work);
-
-       netfs_rreq_do_write_to_cache(rreq);
-}
-
-static void netfs_rreq_write_to_cache(struct netfs_io_request *rreq)
-{
-       rreq->work.func = netfs_rreq_write_to_cache_work;
-       if (!queue_work(system_unbound_wq, &rreq->work))
-               BUG();
-}
-
 /*
  * Handle a short read.
  */
@@ -352,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
        unsigned int i;
        size_t transferred = 0;
 
-       for (i = 0; i < rreq->direct_bv_count; i++)
+       for (i = 0; i < rreq->direct_bv_count; i++) {
                flush_dcache_page(rreq->direct_bv[i].bv_page);
+               // TODO: cifs marks pages in the destination buffer
+               // dirty under some circumstances after a read.  Do we
+               // need to do that too?
+               set_page_dirty(rreq->direct_bv[i].bv_page);
+       }
 
        list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
                if (subreq->error || subreq->transferred == 0)
@@ -409,9 +275,6 @@ again:
        clear_bit_unlock(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
        wake_up_bit(&rreq->flags, NETFS_RREQ_IN_PROGRESS);
 
-       if (test_bit(NETFS_RREQ_COPY_TO_CACHE, &rreq->flags))
-               return netfs_rreq_write_to_cache(rreq);
-
        netfs_rreq_completed(rreq, was_async);
 }
 
@@ -618,7 +481,7 @@ netfs_rreq_prepare_read(struct netfs_io_request *rreq,
 
 set:
        if (subreq->len > rreq->len)
-               pr_warn("R=%08x[%u] SREQ>RREQ %zx > %zx\n",
+               pr_warn("R=%08x[%u] SREQ>RREQ %zx > %llx\n",
                        rreq->debug_id, subreq->debug_index,
                        subreq->len, rreq->len);
 
@@ -643,8 +506,7 @@ out:
  * Slice off a piece of a read request and submit an I/O request for it.
  */
 static bool netfs_rreq_submit_slice(struct netfs_io_request *rreq,
-                                   struct iov_iter *io_iter,
-                                   unsigned int *_debug_index)
+                                   struct iov_iter *io_iter)
 {
        struct netfs_io_subrequest *subreq;
        enum netfs_io_source source;
@@ -653,11 +515,10 @@ static bool netfs_rreq_submit_slice(struct netfs_io_request *rreq,
        if (!subreq)
                return false;
 
-       subreq->debug_index     = (*_debug_index)++;
        subreq->start           = rreq->start + rreq->submitted;
        subreq->len             = io_iter->count;
 
-       _debug("slice %llx,%zx,%zx", subreq->start, subreq->len, rreq->submitted);
+       _debug("slice %llx,%zx,%llx", subreq->start, subreq->len, rreq->submitted);
        list_add_tail(&subreq->rreq_link, &rreq->subrequests);
 
        /* Call out to the cache to find out what it can do with the remaining
@@ -707,7 +568,6 @@ subreq_failed:
 int netfs_begin_read(struct netfs_io_request *rreq, bool sync)
 {
        struct iov_iter io_iter;
-       unsigned int debug_index = 0;
        int ret;
 
        _enter("R=%x %llx-%llx",
@@ -733,12 +593,12 @@ int netfs_begin_read(struct netfs_io_request *rreq, bool sync)
        atomic_set(&rreq->nr_outstanding, 1);
        io_iter = rreq->io_iter;
        do {
-               _debug("submit %llx + %zx >= %llx",
+               _debug("submit %llx + %llx >= %llx",
                       rreq->start, rreq->submitted, rreq->i_size);
                if (rreq->origin == NETFS_DIO_READ &&
                    rreq->start + rreq->submitted >= rreq->i_size)
                        break;
-               if (!netfs_rreq_submit_slice(rreq, &io_iter, &debug_index))
+               if (!netfs_rreq_submit_slice(rreq, &io_iter))
                        break;
                if (test_bit(NETFS_RREQ_BLOCKED, &rreq->flags) &&
                    test_bit(NETFS_RREQ_NONBLOCK, &rreq->flags))
index 5e77618a79409c253ab21aa51c186a07f691f356..5f0f438e5d211d85de06f2c41d1d98144f404639 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/export.h>
+#include <linux/mempool.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include "internal.h"
@@ -23,6 +24,11 @@ unsigned netfs_debug;
 module_param_named(debug, netfs_debug, uint, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(netfs_debug, "Netfs support debugging mask");
 
+static struct kmem_cache *netfs_request_slab;
+static struct kmem_cache *netfs_subrequest_slab;
+mempool_t netfs_request_pool;
+mempool_t netfs_subrequest_pool;
+
 #ifdef CONFIG_PROC_FS
 LIST_HEAD(netfs_io_requests);
 DEFINE_SPINLOCK(netfs_proc_lock);
@@ -31,9 +37,9 @@ static const char *netfs_origins[nr__netfs_io_origin] = {
        [NETFS_READAHEAD]               = "RA",
        [NETFS_READPAGE]                = "RP",
        [NETFS_READ_FOR_WRITE]          = "RW",
+       [NETFS_COPY_TO_CACHE]           = "CC",
        [NETFS_WRITEBACK]               = "WB",
        [NETFS_WRITETHROUGH]            = "WT",
-       [NETFS_LAUNDER_WRITE]           = "LW",
        [NETFS_UNBUFFERED_WRITE]        = "UW",
        [NETFS_DIO_READ]                = "DR",
        [NETFS_DIO_WRITE]               = "DW",
@@ -56,7 +62,7 @@ static int netfs_requests_seq_show(struct seq_file *m, void *v)
 
        rreq = list_entry(v, struct netfs_io_request, proc_link);
        seq_printf(m,
-                  "%08x %s %3d %2lx %4d %3d @%04llx %zx/%zx",
+                  "%08x %s %3d %2lx %4d %3d @%04llx %llx/%llx",
                   rreq->debug_id,
                   netfs_origins[rreq->origin],
                   refcount_read(&rreq->ref),
@@ -98,25 +104,54 @@ static int __init netfs_init(void)
 {
        int ret = -ENOMEM;
 
+       netfs_request_slab = kmem_cache_create("netfs_request",
+                                              sizeof(struct netfs_io_request), 0,
+                                              SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
+                                              NULL);
+       if (!netfs_request_slab)
+               goto error_req;
+
+       if (mempool_init_slab_pool(&netfs_request_pool, 100, netfs_request_slab) < 0)
+               goto error_reqpool;
+
+       netfs_subrequest_slab = kmem_cache_create("netfs_subrequest",
+                                                 sizeof(struct netfs_io_subrequest), 0,
+                                                 SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT,
+                                                 NULL);
+       if (!netfs_subrequest_slab)
+               goto error_subreq;
+
+       if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0)
+               goto error_subreqpool;
+
        if (!proc_mkdir("fs/netfs", NULL))
-               goto error;
+               goto error_proc;
        if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL,
                             &netfs_requests_seq_ops))
-               goto error_proc;
+               goto error_procfile;
 #ifdef CONFIG_FSCACHE_STATS
        if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL,
                                netfs_stats_show))
-               goto error_proc;
+               goto error_procfile;
 #endif
 
        ret = fscache_init();
        if (ret < 0)
-               goto error_proc;
+               goto error_fscache;
        return 0;
 
-error_proc:
+error_fscache:
+error_procfile:
        remove_proc_entry("fs/netfs", NULL);
-error:
+error_proc:
+       mempool_exit(&netfs_subrequest_pool);
+error_subreqpool:
+       kmem_cache_destroy(netfs_subrequest_slab);
+error_subreq:
+       mempool_exit(&netfs_request_pool);
+error_reqpool:
+       kmem_cache_destroy(netfs_request_slab);
+error_req:
        return ret;
 }
 fs_initcall(netfs_init);
@@ -125,5 +160,9 @@ static void __exit netfs_exit(void)
 {
        fscache_exit();
        remove_proc_entry("fs/netfs", NULL);
+       mempool_exit(&netfs_subrequest_pool);
+       kmem_cache_destroy(netfs_subrequest_slab);
+       mempool_exit(&netfs_request_pool);
+       kmem_cache_destroy(netfs_request_slab);
 }
 module_exit(netfs_exit);
index 90051ced8e2a879827e54d4b50c976bc11f6b759..bc1fc54fb724709483fdfdcbf32e106b4aba9716 100644 (file)
@@ -177,13 +177,11 @@ EXPORT_SYMBOL(netfs_clear_inode_writeback);
  */
 void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
 {
-       struct netfs_folio *finfo = NULL;
+       struct netfs_folio *finfo;
        size_t flen = folio_size(folio);
 
        _enter("{%lx},%zx,%zx", folio->index, offset, length);
 
-       folio_wait_fscache(folio);
-
        if (!folio_test_private(folio))
                return;
 
@@ -248,12 +246,6 @@ bool netfs_release_folio(struct folio *folio, gfp_t gfp)
 
        if (folio_test_private(folio))
                return false;
-       if (folio_test_fscache(folio)) {
-               if (current_is_kswapd() || !(gfp & __GFP_FS))
-                       return false;
-               folio_wait_fscache(folio);
-       }
-
        fscache_note_page_release(netfs_i_cookie(ctx));
        return true;
 }
index 610ceb5bd86c08ba7c61905d07d19092940f44ae..c90d482b16505d319dede502bcf23c7bed38e254 100644 (file)
@@ -6,6 +6,8 @@
  */
 
 #include <linux/slab.h>
+#include <linux/mempool.h>
+#include <linux/delay.h>
 #include "internal.h"
 
 /*
@@ -20,17 +22,22 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
        struct inode *inode = file ? file_inode(file) : mapping->host;
        struct netfs_inode *ctx = netfs_inode(inode);
        struct netfs_io_request *rreq;
+       mempool_t *mempool = ctx->ops->request_pool ?: &netfs_request_pool;
+       struct kmem_cache *cache = mempool->pool_data;
        bool is_unbuffered = (origin == NETFS_UNBUFFERED_WRITE ||
                              origin == NETFS_DIO_READ ||
                              origin == NETFS_DIO_WRITE);
        bool cached = !is_unbuffered && netfs_is_cache_enabled(ctx);
        int ret;
 
-       rreq = kzalloc(ctx->ops->io_request_size ?: sizeof(struct netfs_io_request),
-                      GFP_KERNEL);
-       if (!rreq)
-               return ERR_PTR(-ENOMEM);
+       for (;;) {
+               rreq = mempool_alloc(mempool, GFP_KERNEL);
+               if (rreq)
+                       break;
+               msleep(10);
+       }
 
+       memset(rreq, 0, kmem_cache_size(cache));
        rreq->start     = start;
        rreq->len       = len;
        rreq->upper_len = len;
@@ -40,19 +47,27 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
        rreq->inode     = inode;
        rreq->i_size    = i_size_read(inode);
        rreq->debug_id  = atomic_inc_return(&debug_ids);
+       rreq->wsize     = INT_MAX;
+       spin_lock_init(&rreq->lock);
+       INIT_LIST_HEAD(&rreq->io_streams[0].subrequests);
+       INIT_LIST_HEAD(&rreq->io_streams[1].subrequests);
        INIT_LIST_HEAD(&rreq->subrequests);
        INIT_WORK(&rreq->work, NULL);
        refcount_set(&rreq->ref, 1);
 
        __set_bit(NETFS_RREQ_IN_PROGRESS, &rreq->flags);
-       if (cached)
+       if (cached) {
                __set_bit(NETFS_RREQ_WRITE_TO_CACHE, &rreq->flags);
+               if (test_bit(NETFS_ICTX_USE_PGPRIV2, &ctx->flags))
+                       /* Filesystem uses deprecated PG_private_2 marking. */
+                       __set_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags);
+       }
        if (file && file->f_flags & O_NONBLOCK)
                __set_bit(NETFS_RREQ_NONBLOCK, &rreq->flags);
        if (rreq->netfs_ops->init_request) {
                ret = rreq->netfs_ops->init_request(rreq, file);
                if (ret < 0) {
-                       kfree(rreq);
+                       mempool_free(rreq, rreq->netfs_ops->request_pool ?: &netfs_request_pool);
                        return ERR_PTR(ret);
                }
        }
@@ -74,6 +89,8 @@ void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace
 void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async)
 {
        struct netfs_io_subrequest *subreq;
+       struct netfs_io_stream *stream;
+       int s;
 
        while (!list_empty(&rreq->subrequests)) {
                subreq = list_first_entry(&rreq->subrequests,
@@ -82,6 +99,25 @@ void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async)
                netfs_put_subrequest(subreq, was_async,
                                     netfs_sreq_trace_put_clear);
        }
+
+       for (s = 0; s < ARRAY_SIZE(rreq->io_streams); s++) {
+               stream = &rreq->io_streams[s];
+               while (!list_empty(&stream->subrequests)) {
+                       subreq = list_first_entry(&stream->subrequests,
+                                                 struct netfs_io_subrequest, rreq_link);
+                       list_del(&subreq->rreq_link);
+                       netfs_put_subrequest(subreq, was_async,
+                                            netfs_sreq_trace_put_clear);
+               }
+       }
+}
+
+static void netfs_free_request_rcu(struct rcu_head *rcu)
+{
+       struct netfs_io_request *rreq = container_of(rcu, struct netfs_io_request, rcu);
+
+       mempool_free(rreq, rreq->netfs_ops->request_pool ?: &netfs_request_pool);
+       netfs_stat_d(&netfs_n_rh_rreq);
 }
 
 static void netfs_free_request(struct work_struct *work)
@@ -106,8 +142,7 @@ static void netfs_free_request(struct work_struct *work)
                }
                kvfree(rreq->direct_bv);
        }
-       kfree_rcu(rreq, rcu);
-       netfs_stat_d(&netfs_n_rh_rreq);
+       call_rcu(&rreq->rcu, netfs_free_request_rcu);
 }
 
 void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
@@ -139,19 +174,25 @@ void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
 struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq)
 {
        struct netfs_io_subrequest *subreq;
-
-       subreq = kzalloc(rreq->netfs_ops->io_subrequest_size ?:
-                        sizeof(struct netfs_io_subrequest),
-                        GFP_KERNEL);
-       if (subreq) {
-               INIT_WORK(&subreq->work, NULL);
-               INIT_LIST_HEAD(&subreq->rreq_link);
-               refcount_set(&subreq->ref, 2);
-               subreq->rreq = rreq;
-               netfs_get_request(rreq, netfs_rreq_trace_get_subreq);
-               netfs_stat(&netfs_n_rh_sreq);
+       mempool_t *mempool = rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool;
+       struct kmem_cache *cache = mempool->pool_data;
+
+       for (;;) {
+               subreq = mempool_alloc(rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool,
+                                      GFP_KERNEL);
+               if (subreq)
+                       break;
+               msleep(10);
        }
 
+       memset(subreq, 0, kmem_cache_size(cache));
+       INIT_WORK(&subreq->work, NULL);
+       INIT_LIST_HEAD(&subreq->rreq_link);
+       refcount_set(&subreq->ref, 2);
+       subreq->rreq = rreq;
+       subreq->debug_index = atomic_inc_return(&rreq->subreq_counter);
+       netfs_get_request(rreq, netfs_rreq_trace_get_subreq);
+       netfs_stat(&netfs_n_rh_sreq);
        return subreq;
 }
 
@@ -173,7 +214,7 @@ static void netfs_free_subrequest(struct netfs_io_subrequest *subreq,
        trace_netfs_sreq(subreq, netfs_sreq_trace_free);
        if (rreq->netfs_ops->free_subrequest)
                rreq->netfs_ops->free_subrequest(subreq);
-       kfree(subreq);
+       mempool_free(subreq, rreq->netfs_ops->subrequest_pool ?: &netfs_subrequest_pool);
        netfs_stat_d(&netfs_n_rh_sreq);
        netfs_put_request(rreq, was_async, netfs_rreq_trace_put_subreq);
 }
diff --git a/fs/netfs/output.c b/fs/netfs/output.c
deleted file mode 100644 (file)
index 625eb68..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Network filesystem high-level write support.
- *
- * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- */
-
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/writeback.h>
-#include <linux/pagevec.h>
-#include "internal.h"
-
-/**
- * netfs_create_write_request - Create a write operation.
- * @wreq: The write request this is storing from.
- * @dest: The destination type
- * @start: Start of the region this write will modify
- * @len: Length of the modification
- * @worker: The worker function to handle the write(s)
- *
- * Allocate a write operation, set it up and add it to the list on a write
- * request.
- */
-struct netfs_io_subrequest *netfs_create_write_request(struct netfs_io_request *wreq,
-                                                      enum netfs_io_source dest,
-                                                      loff_t start, size_t len,
-                                                      work_func_t worker)
-{
-       struct netfs_io_subrequest *subreq;
-
-       subreq = netfs_alloc_subrequest(wreq);
-       if (subreq) {
-               INIT_WORK(&subreq->work, worker);
-               subreq->source  = dest;
-               subreq->start   = start;
-               subreq->len     = len;
-               subreq->debug_index = wreq->subreq_counter++;
-
-               switch (subreq->source) {
-               case NETFS_UPLOAD_TO_SERVER:
-                       netfs_stat(&netfs_n_wh_upload);
-                       break;
-               case NETFS_WRITE_TO_CACHE:
-                       netfs_stat(&netfs_n_wh_write);
-                       break;
-               default:
-                       BUG();
-               }
-
-               subreq->io_iter = wreq->io_iter;
-               iov_iter_advance(&subreq->io_iter, subreq->start - wreq->start);
-               iov_iter_truncate(&subreq->io_iter, subreq->len);
-
-               trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index,
-                                    refcount_read(&subreq->ref),
-                                    netfs_sreq_trace_new);
-               atomic_inc(&wreq->nr_outstanding);
-               list_add_tail(&subreq->rreq_link, &wreq->subrequests);
-               trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
-       }
-
-       return subreq;
-}
-EXPORT_SYMBOL(netfs_create_write_request);
-
-/*
- * Process a completed write request once all the component operations have
- * been completed.
- */
-static void netfs_write_terminated(struct netfs_io_request *wreq, bool was_async)
-{
-       struct netfs_io_subrequest *subreq;
-       struct netfs_inode *ctx = netfs_inode(wreq->inode);
-       size_t transferred = 0;
-
-       _enter("R=%x[]", wreq->debug_id);
-
-       trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
-
-       list_for_each_entry(subreq, &wreq->subrequests, rreq_link) {
-               if (subreq->error || subreq->transferred == 0)
-                       break;
-               transferred += subreq->transferred;
-               if (subreq->transferred < subreq->len)
-                       break;
-       }
-       wreq->transferred = transferred;
-
-       list_for_each_entry(subreq, &wreq->subrequests, rreq_link) {
-               if (!subreq->error)
-                       continue;
-               switch (subreq->source) {
-               case NETFS_UPLOAD_TO_SERVER:
-                       /* Depending on the type of failure, this may prevent
-                        * writeback completion unless we're in disconnected
-                        * mode.
-                        */
-                       if (!wreq->error)
-                               wreq->error = subreq->error;
-                       break;
-
-               case NETFS_WRITE_TO_CACHE:
-                       /* Failure doesn't prevent writeback completion unless
-                        * we're in disconnected mode.
-                        */
-                       if (subreq->error != -ENOBUFS)
-                               ctx->ops->invalidate_cache(wreq);
-                       break;
-
-               default:
-                       WARN_ON_ONCE(1);
-                       if (!wreq->error)
-                               wreq->error = -EIO;
-                       return;
-               }
-       }
-
-       wreq->cleanup(wreq);
-
-       if (wreq->origin == NETFS_DIO_WRITE &&
-           wreq->mapping->nrpages) {
-               pgoff_t first = wreq->start >> PAGE_SHIFT;
-               pgoff_t last = (wreq->start + wreq->transferred - 1) >> PAGE_SHIFT;
-               invalidate_inode_pages2_range(wreq->mapping, first, last);
-       }
-
-       if (wreq->origin == NETFS_DIO_WRITE)
-               inode_dio_end(wreq->inode);
-
-       _debug("finished");
-       trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip);
-       clear_bit_unlock(NETFS_RREQ_IN_PROGRESS, &wreq->flags);
-       wake_up_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS);
-
-       if (wreq->iocb) {
-               wreq->iocb->ki_pos += transferred;
-               if (wreq->iocb->ki_complete)
-                       wreq->iocb->ki_complete(
-                               wreq->iocb, wreq->error ? wreq->error : transferred);
-       }
-
-       netfs_clear_subrequests(wreq, was_async);
-       netfs_put_request(wreq, was_async, netfs_rreq_trace_put_complete);
-}
-
-/*
- * Deal with the completion of writing the data to the cache.
- */
-void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
-                                      bool was_async)
-{
-       struct netfs_io_subrequest *subreq = _op;
-       struct netfs_io_request *wreq = subreq->rreq;
-       unsigned int u;
-
-       _enter("%x[%x] %zd", wreq->debug_id, subreq->debug_index, transferred_or_error);
-
-       switch (subreq->source) {
-       case NETFS_UPLOAD_TO_SERVER:
-               netfs_stat(&netfs_n_wh_upload_done);
-               break;
-       case NETFS_WRITE_TO_CACHE:
-               netfs_stat(&netfs_n_wh_write_done);
-               break;
-       case NETFS_INVALID_WRITE:
-               break;
-       default:
-               BUG();
-       }
-
-       if (IS_ERR_VALUE(transferred_or_error)) {
-               subreq->error = transferred_or_error;
-               trace_netfs_failure(wreq, subreq, transferred_or_error,
-                                   netfs_fail_write);
-               goto failed;
-       }
-
-       if (WARN(transferred_or_error > subreq->len - subreq->transferred,
-                "Subreq excess write: R%x[%x] %zd > %zu - %zu",
-                wreq->debug_id, subreq->debug_index,
-                transferred_or_error, subreq->len, subreq->transferred))
-               transferred_or_error = subreq->len - subreq->transferred;
-
-       subreq->error = 0;
-       subreq->transferred += transferred_or_error;
-
-       if (iov_iter_count(&subreq->io_iter) != subreq->len - subreq->transferred)
-               pr_warn("R=%08x[%u] ITER POST-MISMATCH %zx != %zx-%zx %x\n",
-                       wreq->debug_id, subreq->debug_index,
-                       iov_iter_count(&subreq->io_iter), subreq->len,
-                       subreq->transferred, subreq->io_iter.iter_type);
-
-       if (subreq->transferred < subreq->len)
-               goto incomplete;
-
-       __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags);
-out:
-       trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
-
-       /* If we decrement nr_outstanding to 0, the ref belongs to us. */
-       u = atomic_dec_return(&wreq->nr_outstanding);
-       if (u == 0)
-               netfs_write_terminated(wreq, was_async);
-       else if (u == 1)
-               wake_up_var(&wreq->nr_outstanding);
-
-       netfs_put_subrequest(subreq, was_async, netfs_sreq_trace_put_terminated);
-       return;
-
-incomplete:
-       if (transferred_or_error == 0) {
-               if (__test_and_set_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags)) {
-                       subreq->error = -ENODATA;
-                       goto failed;
-               }
-       } else {
-               __clear_bit(NETFS_SREQ_NO_PROGRESS, &subreq->flags);
-       }
-
-       __set_bit(NETFS_SREQ_SHORT_IO, &subreq->flags);
-       set_bit(NETFS_RREQ_INCOMPLETE_IO, &wreq->flags);
-       goto out;
-
-failed:
-       switch (subreq->source) {
-       case NETFS_WRITE_TO_CACHE:
-               netfs_stat(&netfs_n_wh_write_failed);
-               set_bit(NETFS_RREQ_INCOMPLETE_IO, &wreq->flags);
-               break;
-       case NETFS_UPLOAD_TO_SERVER:
-               netfs_stat(&netfs_n_wh_upload_failed);
-               set_bit(NETFS_RREQ_FAILED, &wreq->flags);
-               wreq->error = subreq->error;
-               break;
-       default:
-               break;
-       }
-       goto out;
-}
-EXPORT_SYMBOL(netfs_write_subrequest_terminated);
-
-static void netfs_write_to_cache_op(struct netfs_io_subrequest *subreq)
-{
-       struct netfs_io_request *wreq = subreq->rreq;
-       struct netfs_cache_resources *cres = &wreq->cache_resources;
-
-       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
-
-       cres->ops->write(cres, subreq->start, &subreq->io_iter,
-                        netfs_write_subrequest_terminated, subreq);
-}
-
-static void netfs_write_to_cache_op_worker(struct work_struct *work)
-{
-       struct netfs_io_subrequest *subreq =
-               container_of(work, struct netfs_io_subrequest, work);
-
-       netfs_write_to_cache_op(subreq);
-}
-
-/**
- * netfs_queue_write_request - Queue a write request for attention
- * @subreq: The write request to be queued
- *
- * Queue the specified write request for processing by a worker thread.  We
- * pass the caller's ref on the request to the worker thread.
- */
-void netfs_queue_write_request(struct netfs_io_subrequest *subreq)
-{
-       if (!queue_work(system_unbound_wq, &subreq->work))
-               netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_wip);
-}
-EXPORT_SYMBOL(netfs_queue_write_request);
-
-/*
- * Set up a op for writing to the cache.
- */
-static void netfs_set_up_write_to_cache(struct netfs_io_request *wreq)
-{
-       struct netfs_cache_resources *cres = &wreq->cache_resources;
-       struct netfs_io_subrequest *subreq;
-       struct netfs_inode *ctx = netfs_inode(wreq->inode);
-       struct fscache_cookie *cookie = netfs_i_cookie(ctx);
-       loff_t start = wreq->start;
-       size_t len = wreq->len;
-       int ret;
-
-       if (!fscache_cookie_enabled(cookie)) {
-               clear_bit(NETFS_RREQ_WRITE_TO_CACHE, &wreq->flags);
-               return;
-       }
-
-       _debug("write to cache");
-       ret = fscache_begin_write_operation(cres, cookie);
-       if (ret < 0)
-               return;
-
-       ret = cres->ops->prepare_write(cres, &start, &len, wreq->upper_len,
-                                      i_size_read(wreq->inode), true);
-       if (ret < 0)
-               return;
-
-       subreq = netfs_create_write_request(wreq, NETFS_WRITE_TO_CACHE, start, len,
-                                           netfs_write_to_cache_op_worker);
-       if (!subreq)
-               return;
-
-       netfs_write_to_cache_op(subreq);
-}
-
-/*
- * Begin the process of writing out a chunk of data.
- *
- * We are given a write request that holds a series of dirty regions and
- * (partially) covers a sequence of folios, all of which are present.  The
- * pages must have been marked as writeback as appropriate.
- *
- * We need to perform the following steps:
- *
- * (1) If encrypting, create an output buffer and encrypt each block of the
- *     data into it, otherwise the output buffer will point to the original
- *     folios.
- *
- * (2) If the data is to be cached, set up a write op for the entire output
- *     buffer to the cache, if the cache wants to accept it.
- *
- * (3) If the data is to be uploaded (ie. not merely cached):
- *
- *     (a) If the data is to be compressed, create a compression buffer and
- *         compress the data into it.
- *
- *     (b) For each destination we want to upload to, set up write ops to write
- *         to that destination.  We may need multiple writes if the data is not
- *         contiguous or the span exceeds wsize for a server.
- */
-int netfs_begin_write(struct netfs_io_request *wreq, bool may_wait,
-                     enum netfs_write_trace what)
-{
-       struct netfs_inode *ctx = netfs_inode(wreq->inode);
-
-       _enter("R=%x %llx-%llx f=%lx",
-              wreq->debug_id, wreq->start, wreq->start + wreq->len - 1,
-              wreq->flags);
-
-       trace_netfs_write(wreq, what);
-       if (wreq->len == 0 || wreq->iter.count == 0) {
-               pr_err("Zero-sized write [R=%x]\n", wreq->debug_id);
-               return -EIO;
-       }
-
-       if (wreq->origin == NETFS_DIO_WRITE)
-               inode_dio_begin(wreq->inode);
-
-       wreq->io_iter = wreq->iter;
-
-       /* ->outstanding > 0 carries a ref */
-       netfs_get_request(wreq, netfs_rreq_trace_get_for_outstanding);
-       atomic_set(&wreq->nr_outstanding, 1);
-
-       /* Start the encryption/compression going.  We can do that in the
-        * background whilst we generate a list of write ops that we want to
-        * perform.
-        */
-       // TODO: Encrypt or compress the region as appropriate
-
-       /* We need to write all of the region to the cache */
-       if (test_bit(NETFS_RREQ_WRITE_TO_CACHE, &wreq->flags))
-               netfs_set_up_write_to_cache(wreq);
-
-       /* However, we don't necessarily write all of the region to the server.
-        * Caching of reads is being managed this way also.
-        */
-       if (test_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags))
-               ctx->ops->create_write_requests(wreq, wreq->start, wreq->len);
-
-       if (atomic_dec_and_test(&wreq->nr_outstanding))
-               netfs_write_terminated(wreq, false);
-
-       if (!may_wait)
-               return -EIOCBQUEUED;
-
-       wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS,
-                   TASK_UNINTERRUPTIBLE);
-       return wreq->error;
-}
-
-/*
- * Begin a write operation for writing through the pagecache.
- */
-struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len)
-{
-       struct netfs_io_request *wreq;
-       struct file *file = iocb->ki_filp;
-
-       wreq = netfs_alloc_request(file->f_mapping, file, iocb->ki_pos, len,
-                                  NETFS_WRITETHROUGH);
-       if (IS_ERR(wreq))
-               return wreq;
-
-       trace_netfs_write(wreq, netfs_write_trace_writethrough);
-
-       __set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags);
-       iov_iter_xarray(&wreq->iter, ITER_SOURCE, &wreq->mapping->i_pages, wreq->start, 0);
-       wreq->io_iter = wreq->iter;
-
-       /* ->outstanding > 0 carries a ref */
-       netfs_get_request(wreq, netfs_rreq_trace_get_for_outstanding);
-       atomic_set(&wreq->nr_outstanding, 1);
-       return wreq;
-}
-
-static void netfs_submit_writethrough(struct netfs_io_request *wreq, bool final)
-{
-       struct netfs_inode *ictx = netfs_inode(wreq->inode);
-       unsigned long long start;
-       size_t len;
-
-       if (!test_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags))
-               return;
-
-       start = wreq->start + wreq->submitted;
-       len = wreq->iter.count - wreq->submitted;
-       if (!final) {
-               len /= wreq->wsize; /* Round to number of maximum packets */
-               len *= wreq->wsize;
-       }
-
-       ictx->ops->create_write_requests(wreq, start, len);
-       wreq->submitted += len;
-}
-
-/*
- * Advance the state of the write operation used when writing through the
- * pagecache.  Data has been copied into the pagecache that we need to append
- * to the request.  If we've added more than wsize then we need to create a new
- * subrequest.
- */
-int netfs_advance_writethrough(struct netfs_io_request *wreq, size_t copied, bool to_page_end)
-{
-       _enter("ic=%zu sb=%zu ws=%u cp=%zu tp=%u",
-              wreq->iter.count, wreq->submitted, wreq->wsize, copied, to_page_end);
-
-       wreq->iter.count += copied;
-       wreq->io_iter.count += copied;
-       if (to_page_end && wreq->io_iter.count - wreq->submitted >= wreq->wsize)
-               netfs_submit_writethrough(wreq, false);
-
-       return wreq->error;
-}
-
-/*
- * End a write operation used when writing through the pagecache.
- */
-int netfs_end_writethrough(struct netfs_io_request *wreq, struct kiocb *iocb)
-{
-       int ret = -EIOCBQUEUED;
-
-       _enter("ic=%zu sb=%zu ws=%u",
-              wreq->iter.count, wreq->submitted, wreq->wsize);
-
-       if (wreq->submitted < wreq->io_iter.count)
-               netfs_submit_writethrough(wreq, true);
-
-       if (atomic_dec_and_test(&wreq->nr_outstanding))
-               netfs_write_terminated(wreq, false);
-
-       if (is_sync_kiocb(iocb)) {
-               wait_on_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS,
-                           TASK_UNINTERRUPTIBLE);
-               ret = wreq->error;
-       }
-
-       netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
-       return ret;
-}
index deeba9f9dcf5d55f7bf0692ecdf5991334a848ea..0892768eea320e16d828a8a6027e1c7b725b21a8 100644 (file)
@@ -10,9 +10,8 @@
 #include "internal.h"
 
 atomic_t netfs_n_rh_dio_read;
-atomic_t netfs_n_rh_dio_write;
 atomic_t netfs_n_rh_readahead;
-atomic_t netfs_n_rh_readpage;
+atomic_t netfs_n_rh_read_folio;
 atomic_t netfs_n_rh_rreq;
 atomic_t netfs_n_rh_sreq;
 atomic_t netfs_n_rh_download;
@@ -29,6 +28,10 @@ atomic_t netfs_n_rh_write_begin;
 atomic_t netfs_n_rh_write_done;
 atomic_t netfs_n_rh_write_failed;
 atomic_t netfs_n_rh_write_zskip;
+atomic_t netfs_n_wh_buffered_write;
+atomic_t netfs_n_wh_writethrough;
+atomic_t netfs_n_wh_dio_write;
+atomic_t netfs_n_wh_writepages;
 atomic_t netfs_n_wh_wstream_conflict;
 atomic_t netfs_n_wh_upload;
 atomic_t netfs_n_wh_upload_done;
@@ -39,13 +42,17 @@ atomic_t netfs_n_wh_write_failed;
 
 int netfs_stats_show(struct seq_file *m, void *v)
 {
-       seq_printf(m, "Netfs  : DR=%u DW=%u RA=%u RP=%u WB=%u WBZ=%u\n",
+       seq_printf(m, "Netfs  : DR=%u RA=%u RF=%u WB=%u WBZ=%u\n",
                   atomic_read(&netfs_n_rh_dio_read),
-                  atomic_read(&netfs_n_rh_dio_write),
                   atomic_read(&netfs_n_rh_readahead),
-                  atomic_read(&netfs_n_rh_readpage),
+                  atomic_read(&netfs_n_rh_read_folio),
                   atomic_read(&netfs_n_rh_write_begin),
                   atomic_read(&netfs_n_rh_write_zskip));
+       seq_printf(m, "Netfs  : BW=%u WT=%u DW=%u WP=%u\n",
+                  atomic_read(&netfs_n_wh_buffered_write),
+                  atomic_read(&netfs_n_wh_writethrough),
+                  atomic_read(&netfs_n_wh_dio_write),
+                  atomic_read(&netfs_n_wh_writepages));
        seq_printf(m, "Netfs  : ZR=%u sh=%u sk=%u\n",
                   atomic_read(&netfs_n_rh_zero),
                   atomic_read(&netfs_n_rh_short_read),
diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c
new file mode 100644 (file)
index 0000000..60112e4
--- /dev/null
@@ -0,0 +1,808 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Network filesystem write subrequest result collection, assessment
+ * and retrying.
+ *
+ * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+#include "internal.h"
+
+/* Notes made in the collector */
+#define HIT_PENDING            0x01    /* A front op was still pending */
+#define SOME_EMPTY             0x02    /* One of more streams are empty */
+#define ALL_EMPTY              0x04    /* All streams are empty */
+#define MAYBE_DISCONTIG                0x08    /* A front op may be discontiguous (rounded to PAGE_SIZE) */
+#define NEED_REASSESS          0x10    /* Need to loop round and reassess */
+#define REASSESS_DISCONTIG     0x20    /* Reassess discontiguity if contiguity advances */
+#define MADE_PROGRESS          0x40    /* Made progress cleaning up a stream or the folio set */
+#define BUFFERED               0x80    /* The pagecache needs cleaning up */
+#define NEED_RETRY             0x100   /* A front op requests retrying */
+#define SAW_FAILURE            0x200   /* One stream or hit a permanent failure */
+
+/*
+ * Successful completion of write of a folio to the server and/or cache.  Note
+ * that we are not allowed to lock the folio here on pain of deadlocking with
+ * truncate.
+ */
+int netfs_folio_written_back(struct folio *folio)
+{
+       enum netfs_folio_trace why = netfs_folio_trace_clear;
+       struct netfs_folio *finfo;
+       struct netfs_group *group = NULL;
+       int gcount = 0;
+
+       if ((finfo = netfs_folio_info(folio))) {
+               /* Streaming writes cannot be redirtied whilst under writeback,
+                * so discard the streaming record.
+                */
+               folio_detach_private(folio);
+               group = finfo->netfs_group;
+               gcount++;
+               kfree(finfo);
+               why = netfs_folio_trace_clear_s;
+               goto end_wb;
+       }
+
+       if ((group = netfs_folio_group(folio))) {
+               if (group == NETFS_FOLIO_COPY_TO_CACHE) {
+                       why = netfs_folio_trace_clear_cc;
+                       folio_detach_private(folio);
+                       goto end_wb;
+               }
+
+               /* Need to detach the group pointer if the page didn't get
+                * redirtied.  If it has been redirtied, then it must be within
+                * the same group.
+                */
+               why = netfs_folio_trace_redirtied;
+               if (!folio_test_dirty(folio)) {
+                       folio_detach_private(folio);
+                       gcount++;
+                       why = netfs_folio_trace_clear_g;
+               }
+       }
+
+end_wb:
+       trace_netfs_folio(folio, why);
+       folio_end_writeback(folio);
+       return gcount;
+}
+
+/*
+ * Get hold of a folio we have under writeback.  We don't want to get the
+ * refcount on it.
+ */
+static struct folio *netfs_writeback_lookup_folio(struct netfs_io_request *wreq, loff_t pos)
+{
+       XA_STATE(xas, &wreq->mapping->i_pages, pos / PAGE_SIZE);
+       struct folio *folio;
+
+       rcu_read_lock();
+
+       for (;;) {
+               xas_reset(&xas);
+               folio = xas_load(&xas);
+               if (xas_retry(&xas, folio))
+                       continue;
+
+               if (!folio || xa_is_value(folio))
+                       kdebug("R=%08x: folio %lx (%llx) not present",
+                              wreq->debug_id, xas.xa_index, pos / PAGE_SIZE);
+               BUG_ON(!folio || xa_is_value(folio));
+
+               if (folio == xas_reload(&xas))
+                       break;
+       }
+
+       rcu_read_unlock();
+
+       if (WARN_ONCE(!folio_test_writeback(folio),
+                     "R=%08x: folio %lx is not under writeback\n",
+                     wreq->debug_id, folio->index)) {
+               trace_netfs_folio(folio, netfs_folio_trace_not_under_wback);
+       }
+       return folio;
+}
+
+/*
+ * Unlock any folios we've finished with.
+ */
+static void netfs_writeback_unlock_folios(struct netfs_io_request *wreq,
+                                         unsigned long long collected_to,
+                                         unsigned int *notes)
+{
+       for (;;) {
+               struct folio *folio;
+               struct netfs_folio *finfo;
+               unsigned long long fpos, fend;
+               size_t fsize, flen;
+
+               folio = netfs_writeback_lookup_folio(wreq, wreq->cleaned_to);
+
+               fpos = folio_pos(folio);
+               fsize = folio_size(folio);
+               finfo = netfs_folio_info(folio);
+               flen = finfo ? finfo->dirty_offset + finfo->dirty_len : fsize;
+
+               fend = min_t(unsigned long long, fpos + flen, wreq->i_size);
+
+               trace_netfs_collect_folio(wreq, folio, fend, collected_to);
+
+               if (fpos + fsize > wreq->contiguity) {
+                       trace_netfs_collect_contig(wreq, fpos + fsize,
+                                                  netfs_contig_trace_unlock);
+                       wreq->contiguity = fpos + fsize;
+               }
+
+               /* Unlock any folio we've transferred all of. */
+               if (collected_to < fend)
+                       break;
+
+               wreq->nr_group_rel += netfs_folio_written_back(folio);
+               wreq->cleaned_to = fpos + fsize;
+               *notes |= MADE_PROGRESS;
+
+               if (fpos + fsize >= collected_to)
+                       break;
+       }
+}
+
+/*
+ * Perform retries on the streams that need it.
+ */
+static void netfs_retry_write_stream(struct netfs_io_request *wreq,
+                                    struct netfs_io_stream *stream)
+{
+       struct list_head *next;
+
+       _enter("R=%x[%x:]", wreq->debug_id, stream->stream_nr);
+
+       if (list_empty(&stream->subrequests))
+               return;
+
+       if (stream->source == NETFS_UPLOAD_TO_SERVER &&
+           wreq->netfs_ops->retry_request)
+               wreq->netfs_ops->retry_request(wreq, stream);
+
+       if (unlikely(stream->failed))
+               return;
+
+       /* If there's no renegotiation to do, just resend each failed subreq. */
+       if (!stream->prepare_write) {
+               struct netfs_io_subrequest *subreq;
+
+               list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
+                       if (test_bit(NETFS_SREQ_FAILED, &subreq->flags))
+                               break;
+                       if (__test_and_clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
+                               __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
+                               netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
+                               netfs_reissue_write(stream, subreq);
+                       }
+               }
+               return;
+       }
+
+       next = stream->subrequests.next;
+
+       do {
+               struct netfs_io_subrequest *subreq = NULL, *from, *to, *tmp;
+               unsigned long long start, len;
+               size_t part;
+               bool boundary = false;
+
+               /* Go through the stream and find the next span of contiguous
+                * data that we then rejig (cifs, for example, needs the wsize
+                * renegotiating) and reissue.
+                */
+               from = list_entry(next, struct netfs_io_subrequest, rreq_link);
+               to = from;
+               start = from->start + from->transferred;
+               len   = from->len   - from->transferred;
+
+               if (test_bit(NETFS_SREQ_FAILED, &from->flags) ||
+                   !test_bit(NETFS_SREQ_NEED_RETRY, &from->flags))
+                       return;
+
+               list_for_each_continue(next, &stream->subrequests) {
+                       subreq = list_entry(next, struct netfs_io_subrequest, rreq_link);
+                       if (subreq->start + subreq->transferred != start + len ||
+                           test_bit(NETFS_SREQ_BOUNDARY, &subreq->flags) ||
+                           !test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags))
+                               break;
+                       to = subreq;
+                       len += to->len;
+               }
+
+               /* Work through the sublist. */
+               subreq = from;
+               list_for_each_entry_from(subreq, &stream->subrequests, rreq_link) {
+                       if (!len)
+                               break;
+                       /* Renegotiate max_len (wsize) */
+                       trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
+                       __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
+                       __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
+                       stream->prepare_write(subreq);
+
+                       part = min(len, subreq->max_len);
+                       subreq->len = part;
+                       subreq->start = start;
+                       subreq->transferred = 0;
+                       len -= part;
+                       start += part;
+                       if (len && subreq == to &&
+                           __test_and_clear_bit(NETFS_SREQ_BOUNDARY, &to->flags))
+                               boundary = true;
+
+                       netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
+                       netfs_reissue_write(stream, subreq);
+                       if (subreq == to)
+                               break;
+               }
+
+               /* If we managed to use fewer subreqs, we can discard the
+                * excess; if we used the same number, then we're done.
+                */
+               if (!len) {
+                       if (subreq == to)
+                               continue;
+                       list_for_each_entry_safe_from(subreq, tmp,
+                                                     &stream->subrequests, rreq_link) {
+                               trace_netfs_sreq(subreq, netfs_sreq_trace_discard);
+                               list_del(&subreq->rreq_link);
+                               netfs_put_subrequest(subreq, false, netfs_sreq_trace_put_done);
+                               if (subreq == to)
+                                       break;
+                       }
+                       continue;
+               }
+
+               /* We ran out of subrequests, so we need to allocate some more
+                * and insert them after.
+                */
+               do {
+                       subreq = netfs_alloc_subrequest(wreq);
+                       subreq->source          = to->source;
+                       subreq->start           = start;
+                       subreq->max_len         = len;
+                       subreq->max_nr_segs     = INT_MAX;
+                       subreq->debug_index     = atomic_inc_return(&wreq->subreq_counter);
+                       subreq->stream_nr       = to->stream_nr;
+                       __set_bit(NETFS_SREQ_RETRYING, &subreq->flags);
+
+                       trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index,
+                                            refcount_read(&subreq->ref),
+                                            netfs_sreq_trace_new);
+                       netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit);
+
+                       list_add(&subreq->rreq_link, &to->rreq_link);
+                       to = list_next_entry(to, rreq_link);
+                       trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
+
+                       switch (stream->source) {
+                       case NETFS_UPLOAD_TO_SERVER:
+                               netfs_stat(&netfs_n_wh_upload);
+                               subreq->max_len = min(len, wreq->wsize);
+                               break;
+                       case NETFS_WRITE_TO_CACHE:
+                               netfs_stat(&netfs_n_wh_write);
+                               break;
+                       default:
+                               WARN_ON_ONCE(1);
+                       }
+
+                       stream->prepare_write(subreq);
+
+                       part = min(len, subreq->max_len);
+                       subreq->len = subreq->transferred + part;
+                       len -= part;
+                       start += part;
+                       if (!len && boundary) {
+                               __set_bit(NETFS_SREQ_BOUNDARY, &to->flags);
+                               boundary = false;
+                       }
+
+                       netfs_reissue_write(stream, subreq);
+                       if (!len)
+                               break;
+
+               } while (len);
+
+       } while (!list_is_head(next, &stream->subrequests));
+}
+
+/*
+ * Perform retries on the streams that need it.  If we're doing content
+ * encryption and the server copy changed due to a third-party write, we may
+ * need to do an RMW cycle and also rewrite the data to the cache.
+ */
+static void netfs_retry_writes(struct netfs_io_request *wreq)
+{
+       struct netfs_io_subrequest *subreq;
+       struct netfs_io_stream *stream;
+       int s;
+
+       /* Wait for all outstanding I/O to quiesce before performing retries as
+        * we may need to renegotiate the I/O sizes.
+        */
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               stream = &wreq->io_streams[s];
+               if (!stream->active)
+                       continue;
+
+               list_for_each_entry(subreq, &stream->subrequests, rreq_link) {
+                       wait_on_bit(&subreq->flags, NETFS_SREQ_IN_PROGRESS,
+                                   TASK_UNINTERRUPTIBLE);
+               }
+       }
+
+       // TODO: Enc: Fetch changed partial pages
+       // TODO: Enc: Reencrypt content if needed.
+       // TODO: Enc: Wind back transferred point.
+       // TODO: Enc: Mark cache pages for retry.
+
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               stream = &wreq->io_streams[s];
+               if (stream->need_retry) {
+                       stream->need_retry = false;
+                       netfs_retry_write_stream(wreq, stream);
+               }
+       }
+}
+
+/*
+ * Collect and assess the results of various write subrequests.  We may need to
+ * retry some of the results - or even do an RMW cycle for content crypto.
+ *
+ * Note that we have a number of parallel, overlapping lists of subrequests,
+ * one to the server and one to the local cache for example, which may not be
+ * the same size or starting position and may not even correspond in boundary
+ * alignment.
+ */
+static void netfs_collect_write_results(struct netfs_io_request *wreq)
+{
+       struct netfs_io_subrequest *front, *remove;
+       struct netfs_io_stream *stream;
+       unsigned long long collected_to;
+       unsigned int notes;
+       int s;
+
+       _enter("%llx-%llx", wreq->start, wreq->start + wreq->len);
+       trace_netfs_collect(wreq);
+       trace_netfs_rreq(wreq, netfs_rreq_trace_collect);
+
+reassess_streams:
+       smp_rmb();
+       collected_to = ULLONG_MAX;
+       if (wreq->origin == NETFS_WRITEBACK)
+               notes = ALL_EMPTY | BUFFERED | MAYBE_DISCONTIG;
+       else if (wreq->origin == NETFS_WRITETHROUGH)
+               notes = ALL_EMPTY | BUFFERED;
+       else
+               notes = ALL_EMPTY;
+
+       /* Remove completed subrequests from the front of the streams and
+        * advance the completion point on each stream.  We stop when we hit
+        * something that's in progress.  The issuer thread may be adding stuff
+        * to the tail whilst we're doing this.
+        *
+        * We must not, however, merge in discontiguities that span whole
+        * folios that aren't under writeback.  This is made more complicated
+        * by the folios in the gap being of unpredictable sizes - if they even
+        * exist - but we don't want to look them up.
+        */
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               loff_t rstart, rend;
+
+               stream = &wreq->io_streams[s];
+               /* Read active flag before list pointers */
+               if (!smp_load_acquire(&stream->active))
+                       continue;
+
+               front = stream->front;
+               while (front) {
+                       trace_netfs_collect_sreq(wreq, front);
+                       //_debug("sreq [%x] %llx %zx/%zx",
+                       //       front->debug_index, front->start, front->transferred, front->len);
+
+                       /* Stall if there may be a discontinuity. */
+                       rstart = round_down(front->start, PAGE_SIZE);
+                       if (rstart > wreq->contiguity) {
+                               if (wreq->contiguity > stream->collected_to) {
+                                       trace_netfs_collect_gap(wreq, stream,
+                                                               wreq->contiguity, 'D');
+                                       stream->collected_to = wreq->contiguity;
+                               }
+                               notes |= REASSESS_DISCONTIG;
+                               break;
+                       }
+                       rend = round_up(front->start + front->len, PAGE_SIZE);
+                       if (rend > wreq->contiguity) {
+                               trace_netfs_collect_contig(wreq, rend,
+                                                          netfs_contig_trace_collect);
+                               wreq->contiguity = rend;
+                               if (notes & REASSESS_DISCONTIG)
+                                       notes |= NEED_REASSESS;
+                       }
+                       notes &= ~MAYBE_DISCONTIG;
+
+                       /* Stall if the front is still undergoing I/O. */
+                       if (test_bit(NETFS_SREQ_IN_PROGRESS, &front->flags)) {
+                               notes |= HIT_PENDING;
+                               break;
+                       }
+                       smp_rmb(); /* Read counters after I-P flag. */
+
+                       if (stream->failed) {
+                               stream->collected_to = front->start + front->len;
+                               notes |= MADE_PROGRESS | SAW_FAILURE;
+                               goto cancel;
+                       }
+                       if (front->start + front->transferred > stream->collected_to) {
+                               stream->collected_to = front->start + front->transferred;
+                               stream->transferred = stream->collected_to - wreq->start;
+                               notes |= MADE_PROGRESS;
+                       }
+                       if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
+                               stream->failed = true;
+                               stream->error = front->error;
+                               if (stream->source == NETFS_UPLOAD_TO_SERVER)
+                                       mapping_set_error(wreq->mapping, front->error);
+                               notes |= NEED_REASSESS | SAW_FAILURE;
+                               break;
+                       }
+                       if (front->transferred < front->len) {
+                               stream->need_retry = true;
+                               notes |= NEED_RETRY | MADE_PROGRESS;
+                               break;
+                       }
+
+               cancel:
+                       /* Remove if completely consumed. */
+                       spin_lock(&wreq->lock);
+
+                       remove = front;
+                       list_del_init(&front->rreq_link);
+                       front = list_first_entry_or_null(&stream->subrequests,
+                                                        struct netfs_io_subrequest, rreq_link);
+                       stream->front = front;
+                       if (!front) {
+                               unsigned long long jump_to = atomic64_read(&wreq->issued_to);
+
+                               if (stream->collected_to < jump_to) {
+                                       trace_netfs_collect_gap(wreq, stream, jump_to, 'A');
+                                       stream->collected_to = jump_to;
+                               }
+                       }
+
+                       spin_unlock(&wreq->lock);
+                       netfs_put_subrequest(remove, false,
+                                            notes & SAW_FAILURE ?
+                                            netfs_sreq_trace_put_cancel :
+                                            netfs_sreq_trace_put_done);
+               }
+
+               if (front)
+                       notes &= ~ALL_EMPTY;
+               else
+                       notes |= SOME_EMPTY;
+
+               if (stream->collected_to < collected_to)
+                       collected_to = stream->collected_to;
+       }
+
+       if (collected_to != ULLONG_MAX && collected_to > wreq->collected_to)
+               wreq->collected_to = collected_to;
+
+       /* If we have an empty stream, we need to jump it forward over any gap
+        * otherwise the collection point will never advance.
+        *
+        * Note that the issuer always adds to the stream with the lowest
+        * so-far submitted start, so if we see two consecutive subreqs in one
+        * stream with nothing between then in another stream, then the second
+        * stream has a gap that can be jumped.
+        */
+       if (notes & SOME_EMPTY) {
+               unsigned long long jump_to = wreq->start + wreq->len;
+
+               for (s = 0; s < NR_IO_STREAMS; s++) {
+                       stream = &wreq->io_streams[s];
+                       if (stream->active &&
+                           stream->front &&
+                           stream->front->start < jump_to)
+                               jump_to = stream->front->start;
+               }
+
+               for (s = 0; s < NR_IO_STREAMS; s++) {
+                       stream = &wreq->io_streams[s];
+                       if (stream->active &&
+                           !stream->front &&
+                           stream->collected_to < jump_to) {
+                               trace_netfs_collect_gap(wreq, stream, jump_to, 'B');
+                               stream->collected_to = jump_to;
+                       }
+               }
+       }
+
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               stream = &wreq->io_streams[s];
+               if (stream->active)
+                       trace_netfs_collect_stream(wreq, stream);
+       }
+
+       trace_netfs_collect_state(wreq, wreq->collected_to, notes);
+
+       /* Unlock any folios that we have now finished with. */
+       if (notes & BUFFERED) {
+               unsigned long long clean_to = min(wreq->collected_to, wreq->contiguity);
+
+               if (wreq->cleaned_to < clean_to)
+                       netfs_writeback_unlock_folios(wreq, clean_to, &notes);
+       } else {
+               wreq->cleaned_to = wreq->collected_to;
+       }
+
+       // TODO: Discard encryption buffers
+
+       /* If all streams are discontiguous with the last folio we cleared, we
+        * may need to skip a set of folios.
+        */
+       if ((notes & (MAYBE_DISCONTIG | ALL_EMPTY)) == MAYBE_DISCONTIG) {
+               unsigned long long jump_to = ULLONG_MAX;
+
+               for (s = 0; s < NR_IO_STREAMS; s++) {
+                       stream = &wreq->io_streams[s];
+                       if (stream->active && stream->front &&
+                           stream->front->start < jump_to)
+                               jump_to = stream->front->start;
+               }
+
+               trace_netfs_collect_contig(wreq, jump_to, netfs_contig_trace_jump);
+               wreq->contiguity = jump_to;
+               wreq->cleaned_to = jump_to;
+               wreq->collected_to = jump_to;
+               for (s = 0; s < NR_IO_STREAMS; s++) {
+                       stream = &wreq->io_streams[s];
+                       if (stream->collected_to < jump_to)
+                               stream->collected_to = jump_to;
+               }
+               //cond_resched();
+               notes |= MADE_PROGRESS;
+               goto reassess_streams;
+       }
+
+       if (notes & NEED_RETRY)
+               goto need_retry;
+       if ((notes & MADE_PROGRESS) && test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) {
+               trace_netfs_rreq(wreq, netfs_rreq_trace_unpause);
+               clear_bit_unlock(NETFS_RREQ_PAUSE, &wreq->flags);
+               wake_up_bit(&wreq->flags, NETFS_RREQ_PAUSE);
+       }
+
+       if (notes & NEED_REASSESS) {
+               //cond_resched();
+               goto reassess_streams;
+       }
+       if (notes & MADE_PROGRESS) {
+               //cond_resched();
+               goto reassess_streams;
+       }
+
+out:
+       netfs_put_group_many(wreq->group, wreq->nr_group_rel);
+       wreq->nr_group_rel = 0;
+       _leave(" = %x", notes);
+       return;
+
+need_retry:
+       /* Okay...  We're going to have to retry one or both streams.  Note
+        * that any partially completed op will have had any wholly transferred
+        * folios removed from it.
+        */
+       _debug("retry");
+       netfs_retry_writes(wreq);
+       goto out;
+}
+
+/*
+ * Perform the collection of subrequests, folios and encryption buffers.
+ */
+void netfs_write_collection_worker(struct work_struct *work)
+{
+       struct netfs_io_request *wreq = container_of(work, struct netfs_io_request, work);
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+       size_t transferred;
+       int s;
+
+       _enter("R=%x", wreq->debug_id);
+
+       netfs_see_request(wreq, netfs_rreq_trace_see_work);
+       if (!test_bit(NETFS_RREQ_IN_PROGRESS, &wreq->flags)) {
+               netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+               return;
+       }
+
+       netfs_collect_write_results(wreq);
+
+       /* We're done when the app thread has finished posting subreqs and all
+        * the queues in all the streams are empty.
+        */
+       if (!test_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags)) {
+               netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+               return;
+       }
+       smp_rmb(); /* Read ALL_QUEUED before lists. */
+
+       transferred = LONG_MAX;
+       for (s = 0; s < NR_IO_STREAMS; s++) {
+               struct netfs_io_stream *stream = &wreq->io_streams[s];
+               if (!stream->active)
+                       continue;
+               if (!list_empty(&stream->subrequests)) {
+                       netfs_put_request(wreq, false, netfs_rreq_trace_put_work);
+                       return;
+               }
+               if (stream->transferred < transferred)
+                       transferred = stream->transferred;
+       }
+
+       /* Okay, declare that all I/O is complete. */
+       wreq->transferred = transferred;
+       trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
+
+       if (wreq->io_streams[1].active &&
+           wreq->io_streams[1].failed) {
+               /* Cache write failure doesn't prevent writeback completion
+                * unless we're in disconnected mode.
+                */
+               ictx->ops->invalidate_cache(wreq);
+       }
+
+       if (wreq->cleanup)
+               wreq->cleanup(wreq);
+
+       if (wreq->origin == NETFS_DIO_WRITE &&
+           wreq->mapping->nrpages) {
+               /* mmap may have got underfoot and we may now have folios
+                * locally covering the region we just wrote.  Attempt to
+                * discard the folios, but leave in place any modified locally.
+                * ->write_iter() is prevented from interfering by the DIO
+                * counter.
+                */
+               pgoff_t first = wreq->start >> PAGE_SHIFT;
+               pgoff_t last = (wreq->start + wreq->transferred - 1) >> PAGE_SHIFT;
+               invalidate_inode_pages2_range(wreq->mapping, first, last);
+       }
+
+       if (wreq->origin == NETFS_DIO_WRITE)
+               inode_dio_end(wreq->inode);
+
+       _debug("finished");
+       trace_netfs_rreq(wreq, netfs_rreq_trace_wake_ip);
+       clear_bit_unlock(NETFS_RREQ_IN_PROGRESS, &wreq->flags);
+       wake_up_bit(&wreq->flags, NETFS_RREQ_IN_PROGRESS);
+
+       if (wreq->iocb) {
+               wreq->iocb->ki_pos += wreq->transferred;
+               if (wreq->iocb->ki_complete)
+                       wreq->iocb->ki_complete(
+                               wreq->iocb, wreq->error ? wreq->error : wreq->transferred);
+               wreq->iocb = VFS_PTR_POISON;
+       }
+
+       netfs_clear_subrequests(wreq, false);
+       netfs_put_request(wreq, false, netfs_rreq_trace_put_work_complete);
+}
+
+/*
+ * Wake the collection work item.
+ */
+void netfs_wake_write_collector(struct netfs_io_request *wreq, bool was_async)
+{
+       if (!work_pending(&wreq->work)) {
+               netfs_get_request(wreq, netfs_rreq_trace_get_work);
+               if (!queue_work(system_unbound_wq, &wreq->work))
+                       netfs_put_request(wreq, was_async, netfs_rreq_trace_put_work_nq);
+       }
+}
+
+/**
+ * netfs_write_subrequest_terminated - Note the termination of a write operation.
+ * @_op: The I/O request that has terminated.
+ * @transferred_or_error: The amount of data transferred or an error code.
+ * @was_async: The termination was asynchronous
+ *
+ * This tells the library that a contributory write I/O operation has
+ * terminated, one way or another, and that it should collect the results.
+ *
+ * The caller indicates in @transferred_or_error the outcome of the operation,
+ * supplying a positive value to indicate the number of bytes transferred or a
+ * negative error code.  The library will look after reissuing I/O operations
+ * as appropriate and writing downloaded data to the cache.
+ *
+ * If @was_async is true, the caller might be running in softirq or interrupt
+ * context and we can't sleep.
+ *
+ * When this is called, ownership of the subrequest is transferred back to the
+ * library, along with a ref.
+ *
+ * Note that %_op is a void* so that the function can be passed to
+ * kiocb::term_func without the need for a casting wrapper.
+ */
+void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
+                                      bool was_async)
+{
+       struct netfs_io_subrequest *subreq = _op;
+       struct netfs_io_request *wreq = subreq->rreq;
+       struct netfs_io_stream *stream = &wreq->io_streams[subreq->stream_nr];
+
+       _enter("%x[%x] %zd", wreq->debug_id, subreq->debug_index, transferred_or_error);
+
+       switch (subreq->source) {
+       case NETFS_UPLOAD_TO_SERVER:
+               netfs_stat(&netfs_n_wh_upload_done);
+               break;
+       case NETFS_WRITE_TO_CACHE:
+               netfs_stat(&netfs_n_wh_write_done);
+               break;
+       case NETFS_INVALID_WRITE:
+               break;
+       default:
+               BUG();
+       }
+
+       if (IS_ERR_VALUE(transferred_or_error)) {
+               subreq->error = transferred_or_error;
+               if (subreq->error == -EAGAIN)
+                       set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
+               else
+                       set_bit(NETFS_SREQ_FAILED, &subreq->flags);
+               trace_netfs_failure(wreq, subreq, transferred_or_error, netfs_fail_write);
+
+               switch (subreq->source) {
+               case NETFS_WRITE_TO_CACHE:
+                       netfs_stat(&netfs_n_wh_write_failed);
+                       break;
+               case NETFS_UPLOAD_TO_SERVER:
+                       netfs_stat(&netfs_n_wh_upload_failed);
+                       break;
+               default:
+                       break;
+               }
+               trace_netfs_rreq(wreq, netfs_rreq_trace_set_pause);
+               set_bit(NETFS_RREQ_PAUSE, &wreq->flags);
+       } else {
+               if (WARN(transferred_or_error > subreq->len - subreq->transferred,
+                        "Subreq excess write: R=%x[%x] %zd > %zu - %zu",
+                        wreq->debug_id, subreq->debug_index,
+                        transferred_or_error, subreq->len, subreq->transferred))
+                       transferred_or_error = subreq->len - subreq->transferred;
+
+               subreq->error = 0;
+               subreq->transferred += transferred_or_error;
+
+               if (subreq->transferred < subreq->len)
+                       set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
+       }
+
+       trace_netfs_sreq(subreq, netfs_sreq_trace_terminated);
+
+       clear_bit_unlock(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+       wake_up_bit(&subreq->flags, NETFS_SREQ_IN_PROGRESS);
+
+       /* If we are at the head of the queue, wake up the collector,
+        * transferring a ref to it if we were the ones to do so.
+        */
+       if (list_is_first(&subreq->rreq_link, &stream->subrequests))
+               netfs_wake_write_collector(wreq, was_async);
+
+       netfs_put_subrequest(subreq, was_async, netfs_sreq_trace_put_terminated);
+}
+EXPORT_SYMBOL(netfs_write_subrequest_terminated);
diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
new file mode 100644 (file)
index 0000000..e190043
--- /dev/null
@@ -0,0 +1,684 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Network filesystem high-level (buffered) writeback.
+ *
+ * Copyright (C) 2024 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ *
+ * To support network filesystems with local caching, we manage a situation
+ * that can be envisioned like the following:
+ *
+ *               +---+---+-----+-----+---+----------+
+ *    Folios:    |   |   |     |     |   |          |
+ *               +---+---+-----+-----+---+----------+
+ *
+ *                 +------+------+     +----+----+
+ *    Upload:      |      |      |.....|    |    |
+ *  (Stream 0)     +------+------+     +----+----+
+ *
+ *               +------+------+------+------+------+
+ *    Cache:     |      |      |      |      |      |
+ *  (Stream 1)   +------+------+------+------+------+
+ *
+ * Where we have a sequence of folios of varying sizes that we need to overlay
+ * with multiple parallel streams of I/O requests, where the I/O requests in a
+ * stream may also be of various sizes (in cifs, for example, the sizes are
+ * negotiated with the server; in something like ceph, they may represent the
+ * sizes of storage objects).
+ *
+ * The sequence in each stream may contain gaps and noncontiguous subrequests
+ * may be glued together into single vectored write RPCs.
+ */
+
+#include <linux/export.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include "internal.h"
+
+/*
+ * Kill all dirty folios in the event of an unrecoverable error, starting with
+ * a locked folio we've already obtained from writeback_iter().
+ */
+static void netfs_kill_dirty_pages(struct address_space *mapping,
+                                  struct writeback_control *wbc,
+                                  struct folio *folio)
+{
+       int error = 0;
+
+       do {
+               enum netfs_folio_trace why = netfs_folio_trace_kill;
+               struct netfs_group *group = NULL;
+               struct netfs_folio *finfo = NULL;
+               void *priv;
+
+               priv = folio_detach_private(folio);
+               if (priv) {
+                       finfo = __netfs_folio_info(priv);
+                       if (finfo) {
+                               /* Kill folio from streaming write. */
+                               group = finfo->netfs_group;
+                               why = netfs_folio_trace_kill_s;
+                       } else {
+                               group = priv;
+                               if (group == NETFS_FOLIO_COPY_TO_CACHE) {
+                                       /* Kill copy-to-cache folio */
+                                       why = netfs_folio_trace_kill_cc;
+                                       group = NULL;
+                               } else {
+                                       /* Kill folio with group */
+                                       why = netfs_folio_trace_kill_g;
+                               }
+                       }
+               }
+
+               trace_netfs_folio(folio, why);
+
+               folio_start_writeback(folio);
+               folio_unlock(folio);
+               folio_end_writeback(folio);
+
+               netfs_put_group(group);
+               kfree(finfo);
+
+       } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
+}
+
+/*
+ * Create a write request and set it up appropriately for the origin type.
+ */
+struct netfs_io_request *netfs_create_write_req(struct address_space *mapping,
+                                               struct file *file,
+                                               loff_t start,
+                                               enum netfs_io_origin origin)
+{
+       struct netfs_io_request *wreq;
+       struct netfs_inode *ictx;
+
+       wreq = netfs_alloc_request(mapping, file, start, 0, origin);
+       if (IS_ERR(wreq))
+               return wreq;
+
+       _enter("R=%x", wreq->debug_id);
+
+       ictx = netfs_inode(wreq->inode);
+       if (test_bit(NETFS_RREQ_WRITE_TO_CACHE, &wreq->flags))
+               fscache_begin_write_operation(&wreq->cache_resources, netfs_i_cookie(ictx));
+
+       wreq->contiguity = wreq->start;
+       wreq->cleaned_to = wreq->start;
+       INIT_WORK(&wreq->work, netfs_write_collection_worker);
+
+       wreq->io_streams[0].stream_nr           = 0;
+       wreq->io_streams[0].source              = NETFS_UPLOAD_TO_SERVER;
+       wreq->io_streams[0].prepare_write       = ictx->ops->prepare_write;
+       wreq->io_streams[0].issue_write         = ictx->ops->issue_write;
+       wreq->io_streams[0].collected_to        = start;
+       wreq->io_streams[0].transferred         = LONG_MAX;
+
+       wreq->io_streams[1].stream_nr           = 1;
+       wreq->io_streams[1].source              = NETFS_WRITE_TO_CACHE;
+       wreq->io_streams[1].collected_to        = start;
+       wreq->io_streams[1].transferred         = LONG_MAX;
+       if (fscache_resources_valid(&wreq->cache_resources)) {
+               wreq->io_streams[1].avail       = true;
+               wreq->io_streams[1].prepare_write = wreq->cache_resources.ops->prepare_write_subreq;
+               wreq->io_streams[1].issue_write = wreq->cache_resources.ops->issue_write;
+       }
+
+       return wreq;
+}
+
+/**
+ * netfs_prepare_write_failed - Note write preparation failed
+ * @subreq: The subrequest to mark
+ *
+ * Mark a subrequest to note that preparation for write failed.
+ */
+void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq)
+{
+       __set_bit(NETFS_SREQ_FAILED, &subreq->flags);
+       trace_netfs_sreq(subreq, netfs_sreq_trace_prep_failed);
+}
+EXPORT_SYMBOL(netfs_prepare_write_failed);
+
+/*
+ * Prepare a write subrequest.  We need to allocate a new subrequest
+ * if we don't have one.
+ */
+static void netfs_prepare_write(struct netfs_io_request *wreq,
+                               struct netfs_io_stream *stream,
+                               loff_t start)
+{
+       struct netfs_io_subrequest *subreq;
+
+       subreq = netfs_alloc_subrequest(wreq);
+       subreq->source          = stream->source;
+       subreq->start           = start;
+       subreq->max_len         = ULONG_MAX;
+       subreq->max_nr_segs     = INT_MAX;
+       subreq->stream_nr       = stream->stream_nr;
+
+       _enter("R=%x[%x]", wreq->debug_id, subreq->debug_index);
+
+       trace_netfs_sreq_ref(wreq->debug_id, subreq->debug_index,
+                            refcount_read(&subreq->ref),
+                            netfs_sreq_trace_new);
+
+       trace_netfs_sreq(subreq, netfs_sreq_trace_prepare);
+
+       switch (stream->source) {
+       case NETFS_UPLOAD_TO_SERVER:
+               netfs_stat(&netfs_n_wh_upload);
+               subreq->max_len = wreq->wsize;
+               break;
+       case NETFS_WRITE_TO_CACHE:
+               netfs_stat(&netfs_n_wh_write);
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
+
+       if (stream->prepare_write)
+               stream->prepare_write(subreq);
+
+       __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+
+       /* We add to the end of the list whilst the collector may be walking
+        * the list.  The collector only goes nextwards and uses the lock to
+        * remove entries off of the front.
+        */
+       spin_lock(&wreq->lock);
+       list_add_tail(&subreq->rreq_link, &stream->subrequests);
+       if (list_is_first(&subreq->rreq_link, &stream->subrequests)) {
+               stream->front = subreq;
+               if (!stream->active) {
+                       stream->collected_to = stream->front->start;
+                       /* Write list pointers before active flag */
+                       smp_store_release(&stream->active, true);
+               }
+       }
+
+       spin_unlock(&wreq->lock);
+
+       stream->construct = subreq;
+}
+
+/*
+ * Set the I/O iterator for the filesystem/cache to use and dispatch the I/O
+ * operation.  The operation may be asynchronous and should call
+ * netfs_write_subrequest_terminated() when complete.
+ */
+static void netfs_do_issue_write(struct netfs_io_stream *stream,
+                                struct netfs_io_subrequest *subreq)
+{
+       struct netfs_io_request *wreq = subreq->rreq;
+
+       _enter("R=%x[%x],%zx", wreq->debug_id, subreq->debug_index, subreq->len);
+
+       if (test_bit(NETFS_SREQ_FAILED, &subreq->flags))
+               return netfs_write_subrequest_terminated(subreq, subreq->error, false);
+
+       // TODO: Use encrypted buffer
+       if (test_bit(NETFS_RREQ_USE_IO_ITER, &wreq->flags)) {
+               subreq->io_iter = wreq->io_iter;
+               iov_iter_advance(&subreq->io_iter,
+                                subreq->start + subreq->transferred - wreq->start);
+               iov_iter_truncate(&subreq->io_iter,
+                                subreq->len - subreq->transferred);
+       } else {
+               iov_iter_xarray(&subreq->io_iter, ITER_SOURCE, &wreq->mapping->i_pages,
+                               subreq->start + subreq->transferred,
+                               subreq->len   - subreq->transferred);
+       }
+
+       trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
+       stream->issue_write(subreq);
+}
+
+void netfs_reissue_write(struct netfs_io_stream *stream,
+                        struct netfs_io_subrequest *subreq)
+{
+       __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags);
+       netfs_do_issue_write(stream, subreq);
+}
+
+static void netfs_issue_write(struct netfs_io_request *wreq,
+                             struct netfs_io_stream *stream)
+{
+       struct netfs_io_subrequest *subreq = stream->construct;
+
+       if (!subreq)
+               return;
+       stream->construct = NULL;
+
+       if (subreq->start + subreq->len > wreq->start + wreq->submitted)
+               wreq->len = wreq->submitted = subreq->start + subreq->len - wreq->start;
+       netfs_do_issue_write(stream, subreq);
+}
+
+/*
+ * Add data to the write subrequest, dispatching each as we fill it up or if it
+ * is discontiguous with the previous.  We only fill one part at a time so that
+ * we can avoid overrunning the credits obtained (cifs) and try to parallelise
+ * content-crypto preparation with network writes.
+ */
+int netfs_advance_write(struct netfs_io_request *wreq,
+                       struct netfs_io_stream *stream,
+                       loff_t start, size_t len, bool to_eof)
+{
+       struct netfs_io_subrequest *subreq = stream->construct;
+       size_t part;
+
+       if (!stream->avail) {
+               _leave("no write");
+               return len;
+       }
+
+       _enter("R=%x[%x]", wreq->debug_id, subreq ? subreq->debug_index : 0);
+
+       if (subreq && start != subreq->start + subreq->len) {
+               netfs_issue_write(wreq, stream);
+               subreq = NULL;
+       }
+
+       if (!stream->construct)
+               netfs_prepare_write(wreq, stream, start);
+       subreq = stream->construct;
+
+       part = min(subreq->max_len - subreq->len, len);
+       _debug("part %zx/%zx %zx/%zx", subreq->len, subreq->max_len, part, len);
+       subreq->len += part;
+       subreq->nr_segs++;
+
+       if (subreq->len >= subreq->max_len ||
+           subreq->nr_segs >= subreq->max_nr_segs ||
+           to_eof) {
+               netfs_issue_write(wreq, stream);
+               subreq = NULL;
+       }
+
+       return part;
+}
+
+/*
+ * Write some of a pending folio data back to the server.
+ */
+static int netfs_write_folio(struct netfs_io_request *wreq,
+                            struct writeback_control *wbc,
+                            struct folio *folio)
+{
+       struct netfs_io_stream *upload = &wreq->io_streams[0];
+       struct netfs_io_stream *cache  = &wreq->io_streams[1];
+       struct netfs_io_stream *stream;
+       struct netfs_group *fgroup; /* TODO: Use this with ceph */
+       struct netfs_folio *finfo;
+       size_t fsize = folio_size(folio), flen = fsize, foff = 0;
+       loff_t fpos = folio_pos(folio), i_size;
+       bool to_eof = false, streamw = false;
+       bool debug = false;
+
+       _enter("");
+
+       /* netfs_perform_write() may shift i_size around the page or from out
+        * of the page to beyond it, but cannot move i_size into or through the
+        * page since we have it locked.
+        */
+       i_size = i_size_read(wreq->inode);
+
+       if (fpos >= i_size) {
+               /* mmap beyond eof. */
+               _debug("beyond eof");
+               folio_start_writeback(folio);
+               folio_unlock(folio);
+               wreq->nr_group_rel += netfs_folio_written_back(folio);
+               netfs_put_group_many(wreq->group, wreq->nr_group_rel);
+               wreq->nr_group_rel = 0;
+               return 0;
+       }
+
+       if (fpos + fsize > wreq->i_size)
+               wreq->i_size = i_size;
+
+       fgroup = netfs_folio_group(folio);
+       finfo = netfs_folio_info(folio);
+       if (finfo) {
+               foff = finfo->dirty_offset;
+               flen = foff + finfo->dirty_len;
+               streamw = true;
+       }
+
+       if (wreq->origin == NETFS_WRITETHROUGH) {
+               to_eof = false;
+               if (flen > i_size - fpos)
+                       flen = i_size - fpos;
+       } else if (flen > i_size - fpos) {
+               flen = i_size - fpos;
+               if (!streamw)
+                       folio_zero_segment(folio, flen, fsize);
+               to_eof = true;
+       } else if (flen == i_size - fpos) {
+               to_eof = true;
+       }
+       flen -= foff;
+
+       _debug("folio %zx %zx %zx", foff, flen, fsize);
+
+       /* Deal with discontinuities in the stream of dirty pages.  These can
+        * arise from a number of sources:
+        *
+        * (1) Intervening non-dirty pages from random-access writes, multiple
+        *     flushers writing back different parts simultaneously and manual
+        *     syncing.
+        *
+        * (2) Partially-written pages from write-streaming.
+        *
+        * (3) Pages that belong to a different write-back group (eg.  Ceph
+        *     snapshots).
+        *
+        * (4) Actually-clean pages that were marked for write to the cache
+        *     when they were read.  Note that these appear as a special
+        *     write-back group.
+        */
+       if (fgroup == NETFS_FOLIO_COPY_TO_CACHE) {
+               netfs_issue_write(wreq, upload);
+       } else if (fgroup != wreq->group) {
+               /* We can't write this page to the server yet. */
+               kdebug("wrong group");
+               folio_redirty_for_writepage(wbc, folio);
+               folio_unlock(folio);
+               netfs_issue_write(wreq, upload);
+               netfs_issue_write(wreq, cache);
+               return 0;
+       }
+
+       if (foff > 0)
+               netfs_issue_write(wreq, upload);
+       if (streamw)
+               netfs_issue_write(wreq, cache);
+
+       /* Flip the page to the writeback state and unlock.  If we're called
+        * from write-through, then the page has already been put into the wb
+        * state.
+        */
+       if (wreq->origin == NETFS_WRITEBACK)
+               folio_start_writeback(folio);
+       folio_unlock(folio);
+
+       if (fgroup == NETFS_FOLIO_COPY_TO_CACHE) {
+               if (!fscache_resources_valid(&wreq->cache_resources)) {
+                       trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
+                       netfs_issue_write(wreq, upload);
+                       netfs_folio_written_back(folio);
+                       return 0;
+               }
+               trace_netfs_folio(folio, netfs_folio_trace_store_copy);
+       } else if (!upload->construct) {
+               trace_netfs_folio(folio, netfs_folio_trace_store);
+       } else {
+               trace_netfs_folio(folio, netfs_folio_trace_store_plus);
+       }
+
+       /* Move the submission point forward to allow for write-streaming data
+        * not starting at the front of the page.  We don't do write-streaming
+        * with the cache as the cache requires DIO alignment.
+        *
+        * Also skip uploading for data that's been read and just needs copying
+        * to the cache.
+        */
+       for (int s = 0; s < NR_IO_STREAMS; s++) {
+               stream = &wreq->io_streams[s];
+               stream->submit_max_len = fsize;
+               stream->submit_off = foff;
+               stream->submit_len = flen;
+               if ((stream->source == NETFS_WRITE_TO_CACHE && streamw) ||
+                   (stream->source == NETFS_UPLOAD_TO_SERVER &&
+                    fgroup == NETFS_FOLIO_COPY_TO_CACHE)) {
+                       stream->submit_off = UINT_MAX;
+                       stream->submit_len = 0;
+                       stream->submit_max_len = 0;
+               }
+       }
+
+       /* Attach the folio to one or more subrequests.  For a big folio, we
+        * could end up with thousands of subrequests if the wsize is small -
+        * but we might need to wait during the creation of subrequests for
+        * network resources (eg. SMB credits).
+        */
+       for (;;) {
+               ssize_t part;
+               size_t lowest_off = ULONG_MAX;
+               int choose_s = -1;
+
+               /* Always add to the lowest-submitted stream first. */
+               for (int s = 0; s < NR_IO_STREAMS; s++) {
+                       stream = &wreq->io_streams[s];
+                       if (stream->submit_len > 0 &&
+                           stream->submit_off < lowest_off) {
+                               lowest_off = stream->submit_off;
+                               choose_s = s;
+                       }
+               }
+
+               if (choose_s < 0)
+                       break;
+               stream = &wreq->io_streams[choose_s];
+
+               part = netfs_advance_write(wreq, stream, fpos + stream->submit_off,
+                                          stream->submit_len, to_eof);
+               atomic64_set(&wreq->issued_to, fpos + stream->submit_off);
+               stream->submit_off += part;
+               stream->submit_max_len -= part;
+               if (part > stream->submit_len)
+                       stream->submit_len = 0;
+               else
+                       stream->submit_len -= part;
+               if (part > 0)
+                       debug = true;
+       }
+
+       atomic64_set(&wreq->issued_to, fpos + fsize);
+
+       if (!debug)
+               kdebug("R=%x: No submit", wreq->debug_id);
+
+       if (flen < fsize)
+               for (int s = 0; s < NR_IO_STREAMS; s++)
+                       netfs_issue_write(wreq, &wreq->io_streams[s]);
+
+       _leave(" = 0");
+       return 0;
+}
+
+/*
+ * Write some of the pending data back to the server
+ */
+int netfs_writepages(struct address_space *mapping,
+                    struct writeback_control *wbc)
+{
+       struct netfs_inode *ictx = netfs_inode(mapping->host);
+       struct netfs_io_request *wreq = NULL;
+       struct folio *folio;
+       int error = 0;
+
+       if (wbc->sync_mode == WB_SYNC_ALL)
+               mutex_lock(&ictx->wb_lock);
+       else if (!mutex_trylock(&ictx->wb_lock))
+               return 0;
+
+       /* Need the first folio to be able to set up the op. */
+       folio = writeback_iter(mapping, wbc, NULL, &error);
+       if (!folio)
+               goto out;
+
+       wreq = netfs_create_write_req(mapping, NULL, folio_pos(folio), NETFS_WRITEBACK);
+       if (IS_ERR(wreq)) {
+               error = PTR_ERR(wreq);
+               goto couldnt_start;
+       }
+
+       trace_netfs_write(wreq, netfs_write_trace_writeback);
+       netfs_stat(&netfs_n_wh_writepages);
+
+       do {
+               _debug("wbiter %lx %llx", folio->index, wreq->start + wreq->submitted);
+
+               /* It appears we don't have to handle cyclic writeback wrapping. */
+               WARN_ON_ONCE(wreq && folio_pos(folio) < wreq->start + wreq->submitted);
+
+               if (netfs_folio_group(folio) != NETFS_FOLIO_COPY_TO_CACHE &&
+                   unlikely(!test_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags))) {
+                       set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags);
+                       wreq->netfs_ops->begin_writeback(wreq);
+               }
+
+               error = netfs_write_folio(wreq, wbc, folio);
+               if (error < 0)
+                       break;
+       } while ((folio = writeback_iter(mapping, wbc, folio, &error)));
+
+       for (int s = 0; s < NR_IO_STREAMS; s++)
+               netfs_issue_write(wreq, &wreq->io_streams[s]);
+       smp_wmb(); /* Write lists before ALL_QUEUED. */
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+
+       mutex_unlock(&ictx->wb_lock);
+
+       netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
+       _leave(" = %d", error);
+       return error;
+
+couldnt_start:
+       netfs_kill_dirty_pages(mapping, wbc, folio);
+out:
+       mutex_unlock(&ictx->wb_lock);
+       _leave(" = %d", error);
+       return error;
+}
+EXPORT_SYMBOL(netfs_writepages);
+
+/*
+ * Begin a write operation for writing through the pagecache.
+ */
+struct netfs_io_request *netfs_begin_writethrough(struct kiocb *iocb, size_t len)
+{
+       struct netfs_io_request *wreq = NULL;
+       struct netfs_inode *ictx = netfs_inode(file_inode(iocb->ki_filp));
+
+       mutex_lock(&ictx->wb_lock);
+
+       wreq = netfs_create_write_req(iocb->ki_filp->f_mapping, iocb->ki_filp,
+                                     iocb->ki_pos, NETFS_WRITETHROUGH);
+       if (IS_ERR(wreq)) {
+               mutex_unlock(&ictx->wb_lock);
+               return wreq;
+       }
+
+       wreq->io_streams[0].avail = true;
+       trace_netfs_write(wreq, netfs_write_trace_writethrough);
+       return wreq;
+}
+
+/*
+ * Advance the state of the write operation used when writing through the
+ * pagecache.  Data has been copied into the pagecache that we need to append
+ * to the request.  If we've added more than wsize then we need to create a new
+ * subrequest.
+ */
+int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+                              struct folio *folio, size_t copied, bool to_page_end,
+                              struct folio **writethrough_cache)
+{
+       _enter("R=%x ic=%zu ws=%u cp=%zu tp=%u",
+              wreq->debug_id, wreq->iter.count, wreq->wsize, copied, to_page_end);
+
+       if (!*writethrough_cache) {
+               if (folio_test_dirty(folio))
+                       /* Sigh.  mmap. */
+                       folio_clear_dirty_for_io(folio);
+
+               /* We can make multiple writes to the folio... */
+               folio_start_writeback(folio);
+               if (wreq->len == 0)
+                       trace_netfs_folio(folio, netfs_folio_trace_wthru);
+               else
+                       trace_netfs_folio(folio, netfs_folio_trace_wthru_plus);
+               *writethrough_cache = folio;
+       }
+
+       wreq->len += copied;
+       if (!to_page_end)
+               return 0;
+
+       *writethrough_cache = NULL;
+       return netfs_write_folio(wreq, wbc, folio);
+}
+
+/*
+ * End a write operation used when writing through the pagecache.
+ */
+int netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc,
+                          struct folio *writethrough_cache)
+{
+       struct netfs_inode *ictx = netfs_inode(wreq->inode);
+       int ret;
+
+       _enter("R=%x", wreq->debug_id);
+
+       if (writethrough_cache)
+               netfs_write_folio(wreq, wbc, writethrough_cache);
+
+       netfs_issue_write(wreq, &wreq->io_streams[0]);
+       netfs_issue_write(wreq, &wreq->io_streams[1]);
+       smp_wmb(); /* Write lists before ALL_QUEUED. */
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+
+       mutex_unlock(&ictx->wb_lock);
+
+       ret = wreq->error;
+       netfs_put_request(wreq, false, netfs_rreq_trace_put_return);
+       return ret;
+}
+
+/*
+ * Write data to the server without going through the pagecache and without
+ * writing it to the local cache.
+ */
+int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t len)
+{
+       struct netfs_io_stream *upload = &wreq->io_streams[0];
+       ssize_t part;
+       loff_t start = wreq->start;
+       int error = 0;
+
+       _enter("%zx", len);
+
+       if (wreq->origin == NETFS_DIO_WRITE)
+               inode_dio_begin(wreq->inode);
+
+       while (len) {
+               // TODO: Prepare content encryption
+
+               _debug("unbuffered %zx", len);
+               part = netfs_advance_write(wreq, upload, start, len, false);
+               start += part;
+               len -= part;
+               if (test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) {
+                       trace_netfs_rreq(wreq, netfs_rreq_trace_wait_pause);
+                       wait_on_bit(&wreq->flags, NETFS_RREQ_PAUSE, TASK_UNINTERRUPTIBLE);
+               }
+               if (test_bit(NETFS_RREQ_FAILED, &wreq->flags))
+                       break;
+       }
+
+       netfs_issue_write(wreq, upload);
+
+       smp_wmb(); /* Write lists before ALL_QUEUED. */
+       set_bit(NETFS_RREQ_ALL_QUEUED, &wreq->flags);
+       if (list_empty(&upload->subrequests))
+               netfs_wake_write_collector(wreq, false);
+
+       _leave(" = %d", error);
+       return error;
+}
index 407c6e15afe25c4fd5a6dc452f41d55438d7fb24..6bd127e6683dcef2bef33ec721821e787c10098d 100644 (file)
@@ -433,7 +433,7 @@ static void nfs_invalidate_folio(struct folio *folio, size_t offset,
                return;
        /* Cancel any unstarted writes on this page */
        nfs_wb_folio_cancel(inode, folio);
-       folio_wait_fscache(folio);
+       folio_wait_private_2(folio); /* [DEPRECATED] */
        trace_nfs_invalidate_folio(inode, folio);
 }
 
@@ -500,7 +500,7 @@ static int nfs_launder_folio(struct folio *folio)
        dfprintk(PAGECACHE, "NFS: launder_folio(%ld, %llu)\n",
                inode->i_ino, folio_pos(folio));
 
-       folio_wait_fscache(folio);
+       folio_wait_private_2(folio); /* [DEPRECATED] */
        ret = nfs_wb_folio(inode, folio);
        trace_nfs_launder_folio_done(inode, folio, ret);
        return ret;
@@ -593,8 +593,8 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
        sb_start_pagefault(inode->i_sb);
 
        /* make sure the cache has finished storing the page */
-       if (folio_test_fscache(folio) &&
-           folio_wait_fscache_killable(folio) < 0) {
+       if (folio_test_private_2(folio) && /* [DEPRECATED] */
+           folio_wait_private_2_killable(folio) < 0) {
                ret = VM_FAULT_RETRY;
                goto out;
        }
index e3cb4923316b2cc044fd87ef6399c867ba19663c..fbed0027996f8840ddbe7a16ebe457fa684c525c 100644 (file)
@@ -81,6 +81,8 @@ static inline void nfs_netfs_put(struct nfs_netfs_io_data *netfs)
 static inline void nfs_netfs_inode_init(struct nfs_inode *nfsi)
 {
        netfs_inode_init(&nfsi->netfs, &nfs_netfs_ops, false);
+       /* [DEPRECATED] Use PG_private_2 to mark folio being written to the cache. */
+       __set_bit(NETFS_ICTX_USE_PGPRIV2, &nfsi->netfs.flags);
 }
 extern void nfs_netfs_initiate_read(struct nfs_pgio_header *hdr);
 extern void nfs_netfs_read_completion(struct nfs_pgio_header *hdr);
@@ -101,10 +103,10 @@ extern int nfs_netfs_read_folio(struct file *file, struct folio *folio);
 
 static inline bool nfs_fscache_release_folio(struct folio *folio, gfp_t gfp)
 {
-       if (folio_test_fscache(folio)) {
+       if (folio_test_private_2(folio)) { /* [DEPRECATED] */
                if (current_is_kswapd() || !(gfp & __GFP_FS))
                        return false;
-               folio_wait_fscache(folio);
+               folio_wait_private_2(folio);
        }
        fscache_note_page_release(netfs_i_cookie(netfs_inode(folio->mapping->host)));
        return true;
index c709c296ea9a49e0ccecdae975a5287aea5759fe..acef52ecb1bb7ee01ff448f0c066d4bc1c9df932 100644 (file)
@@ -2429,7 +2429,12 @@ static int nfs_net_init(struct net *net)
        struct nfs_net *nn = net_generic(net, nfs_net_id);
 
        nfs_clients_init(net);
-       rpc_proc_register(net, &nn->rpcstats);
+
+       if (!rpc_proc_register(net, &nn->rpcstats)) {
+               nfs_clients_exit(net);
+               return -ENOMEM;
+       }
+
        return nfs_fs_proc_net_init(net);
 }
 
index 5de85d725fb95fdd19fe814aba607c5249267a6a..2329cbb0e446b97976de4ba587315957fb921a54 100644 (file)
@@ -2120,10 +2120,10 @@ int nfs_migrate_folio(struct address_space *mapping, struct folio *dst,
        if (folio_test_private(src))
                return -EBUSY;
 
-       if (folio_test_fscache(src)) {
+       if (folio_test_private_2(src)) { /* [DEPRECATED] */
                if (mode == MIGRATE_ASYNC)
                        return -EBUSY;
-               folio_wait_fscache(src);
+               folio_wait_private_2(src);
        }
 
        return migrate_folio(mapping, dst, src, mode);
index 1955481832e03796170ea8f80361bc25cc452ca6..a644460f3a5e7a7e3f8574ab922fef1e94ccb753 100644 (file)
@@ -3515,6 +3515,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
        args.exp = exp;
        args.dentry = dentry;
        args.ignore_crossmnt = (ignore_crossmnt != 0);
+       args.acl = NULL;
 
        /*
         * Make a local copy of the attribute bitmap that can be modified.
@@ -3573,7 +3574,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
        } else
                args.fhp = fhp;
 
-       args.acl = NULL;
        if (attrmask[0] & FATTR4_WORD0_ACL) {
                err = nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl);
                if (err == -EOPNOTSUPP)
index f1a01c191cf53ad17131fcf2a256f70b37d0d86c..8be471ce4f1950029e2f7479cd46f0369215b121 100644 (file)
@@ -60,7 +60,7 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
        if (argv->v_nmembs == 0)
                return 0;
 
-       if (argv->v_size > PAGE_SIZE)
+       if ((size_t)argv->v_size > PAGE_SIZE)
                return -EINVAL;
 
        /*
index 4a0779e3ef792334904f18bfc5b5c791a7141768..a7b527ea50d3ca6962313958c93601e46eee1a35 100644 (file)
@@ -355,10 +355,10 @@ static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
        return inode;
 }
 
-static int openprom_remount(struct super_block *sb, int *flags, char *data)
+static int openpromfs_reconfigure(struct fs_context *fc)
 {
-       sync_filesystem(sb);
-       *flags |= SB_NOATIME;
+       sync_filesystem(fc->root->d_sb);
+       fc->sb_flags |= SB_NOATIME;
        return 0;
 }
 
@@ -366,7 +366,6 @@ static const struct super_operations openprom_sops = {
        .alloc_inode    = openprom_alloc_inode,
        .free_inode     = openprom_free_inode,
        .statfs         = simple_statfs,
-       .remount_fs     = openprom_remount,
 };
 
 static int openprom_fill_super(struct super_block *s, struct fs_context *fc)
@@ -415,6 +414,7 @@ static int openpromfs_get_tree(struct fs_context *fc)
 
 static const struct fs_context_operations openpromfs_context_ops = {
        .get_tree       = openpromfs_get_tree,
+       .reconfigure    = openpromfs_reconfigure,
 };
 
 static int openpromfs_init_fs_context(struct fs_context *fc)
index 8bbe9486e3a6228c40c46971d23c305127e2007b..395a00ed8ac75f64b6a4c122ff843689b42f6cac 100644 (file)
@@ -33,9 +33,7 @@ static int orangefs_revalidate_lookup(struct dentry *dentry)
 
        new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
        new_op->upcall.req.lookup.parent_refn = parent->refn;
-       strncpy(new_op->upcall.req.lookup.d_name,
-               dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name);
 
        gossip_debug(GOSSIP_DCACHE_DEBUG,
                     "%s:%s:%d interrupt flag [%d]\n",
index c9dfd5c6a0970c1d9de8e917f26da4b5b4d50dde..200558ec72f086c36ab53567b0fc7ea93f2e9675 100644 (file)
@@ -41,8 +41,7 @@ static int orangefs_create(struct mnt_idmap *idmap,
        fill_default_sys_attrs(new_op->upcall.req.create.attributes,
                               ORANGEFS_TYPE_METAFILE, mode);
 
-       strncpy(new_op->upcall.req.create.d_name,
-               dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.create.d_name, dentry->d_name.name);
 
        ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
 
@@ -137,8 +136,7 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
                     &parent->refn.khandle);
        new_op->upcall.req.lookup.parent_refn = parent->refn;
 
-       strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name);
 
        gossip_debug(GOSSIP_NAME_DEBUG,
                     "%s: doing lookup on %s under %pU,%d\n",
@@ -192,8 +190,7 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
                return -ENOMEM;
 
        new_op->upcall.req.remove.parent_refn = parent->refn;
-       strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.remove.d_name, dentry->d_name.name);
 
        ret = service_operation(new_op, "orangefs_unlink",
                                get_interruptible_flag(inode));
@@ -247,10 +244,8 @@ static int orangefs_symlink(struct mnt_idmap *idmap,
                               ORANGEFS_TYPE_SYMLINK,
                               mode);
 
-       strncpy(new_op->upcall.req.sym.entry_name,
-               dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
-       strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.sym.entry_name, dentry->d_name.name);
+       strscpy(new_op->upcall.req.sym.target, symname);
 
        ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
 
@@ -324,8 +319,7 @@ static int orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
        fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
                              ORANGEFS_TYPE_DIRECTORY, mode);
 
-       strncpy(new_op->upcall.req.mkdir.d_name,
-               dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.mkdir.d_name, dentry->d_name.name);
 
        ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
 
@@ -405,12 +399,8 @@ static int orangefs_rename(struct mnt_idmap *idmap,
        new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn;
        new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn;
 
-       strncpy(new_op->upcall.req.rename.d_old_name,
-               old_dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
-       strncpy(new_op->upcall.req.rename.d_new_name,
-               new_dentry->d_name.name,
-               ORANGEFS_NAME_MAX - 1);
+       strscpy(new_op->upcall.req.rename.d_old_name, old_dentry->d_name.name);
+       strscpy(new_op->upcall.req.rename.d_new_name, new_dentry->d_name.name);
 
        ret = service_operation(new_op,
                                "orangefs_rename",
index 34849b4a3243ca5a2d27114d8a6f5f0a6074d329..fb4d09c2f531f0e668daf135323484bfa6023e80 100644 (file)
@@ -253,9 +253,8 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb)
        new_op = op_alloc(ORANGEFS_VFS_OP_FS_MOUNT);
        if (!new_op)
                return -ENOMEM;
-       strncpy(new_op->upcall.req.fs_mount.orangefs_config_server,
-               orangefs_sb->devname,
-               ORANGEFS_MAX_SERVER_ADDR_LEN);
+       strscpy(new_op->upcall.req.fs_mount.orangefs_config_server,
+               orangefs_sb->devname);
 
        gossip_debug(GOSSIP_SUPER_DEBUG,
                     "Attempting ORANGEFS Remount via host %s\n",
@@ -400,8 +399,7 @@ static int orangefs_unmount(int id, __s32 fs_id, const char *devname)
                return -ENOMEM;
        op->upcall.req.fs_umount.id = id;
        op->upcall.req.fs_umount.fs_id = fs_id;
-       strncpy(op->upcall.req.fs_umount.orangefs_config_server,
-           devname, ORANGEFS_MAX_SERVER_ADDR_LEN - 1);
+       strscpy(op->upcall.req.fs_umount.orangefs_config_server, devname);
        r = service_operation(op, "orangefs_fs_umount", 0);
        /* Not much to do about an error here. */
        if (r)
@@ -494,9 +492,7 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
        if (!new_op)
                return ERR_PTR(-ENOMEM);
 
-       strncpy(new_op->upcall.req.fs_mount.orangefs_config_server,
-               devname,
-               ORANGEFS_MAX_SERVER_ADDR_LEN - 1);
+       strscpy(new_op->upcall.req.fs_mount.orangefs_config_server, devname);
 
        gossip_debug(GOSSIP_SUPER_DEBUG,
                     "Attempting ORANGEFS Mount via host %s\n",
@@ -543,9 +539,8 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
         * on successful mount, store the devname and data
         * used
         */
-       strncpy(ORANGEFS_SB(sb)->devname,
-               devname,
-               ORANGEFS_MAX_SERVER_ADDR_LEN - 1);
+       strscpy(ORANGEFS_SB(sb)->devname, devname);
+
 
        /* mount_pending must be cleared */
        ORANGEFS_SB(sb)->mount_pending = 0;
index 36dcc530ac286b0102e228acebdf03a5951fa57b..4860fcc4611bb766547218d1baa9fd802f24f547 100644 (file)
@@ -139,10 +139,6 @@ static int ovl_verity_mode_def(void)
        return OVL_VERITY_OFF;
 }
 
-#define fsparam_string_empty(NAME, OPT) \
-       __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL)
-
-
 const struct fs_parameter_spec ovl_parameter_spec[] = {
        fsparam_string_empty("lowerdir",    Opt_lowerdir),
        fsparam_string("lowerdir+",         Opt_lowerdir_add),
index 6e72e5ad42bc74b8f7135c00ce5bca93b1dcb8ac..f4b1c8b42a511320f6586a6ccd530b17d990aa42 100644 (file)
@@ -74,7 +74,18 @@ out:
        return 0;
 }
 
-static int proc_fdinfo_access_allowed(struct inode *inode)
+static int seq_fdinfo_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, seq_show, inode);
+}
+
+/**
+ * Shared /proc/pid/fdinfo and /proc/pid/fdinfo/fd permission helper to ensure
+ * that the current task has PTRACE_MODE_READ in addition to the normal
+ * POSIX-like checks.
+ */
+static int proc_fdinfo_permission(struct mnt_idmap *idmap, struct inode *inode,
+                                 int mask)
 {
        bool allowed = false;
        struct task_struct *task = get_proc_task(inode);
@@ -88,18 +99,13 @@ static int proc_fdinfo_access_allowed(struct inode *inode)
        if (!allowed)
                return -EACCES;
 
-       return 0;
+       return generic_permission(idmap, inode, mask);
 }
 
-static int seq_fdinfo_open(struct inode *inode, struct file *file)
-{
-       int ret = proc_fdinfo_access_allowed(inode);
-
-       if (ret)
-               return ret;
-
-       return single_open(file, seq_show, inode);
-}
+static const struct inode_operations proc_fdinfo_file_inode_operations = {
+       .permission     = proc_fdinfo_permission,
+       .setattr        = proc_setattr,
+};
 
 static const struct file_operations proc_fdinfo_file_operations = {
        .open           = seq_fdinfo_open,
@@ -388,6 +394,8 @@ static struct dentry *proc_fdinfo_instantiate(struct dentry *dentry,
        ei = PROC_I(inode);
        ei->fd = data->fd;
 
+       inode->i_op = &proc_fdinfo_file_inode_operations;
+
        inode->i_fop = &proc_fdinfo_file_operations;
        tid_fd_update_inode(task, inode, 0);
 
@@ -407,23 +415,13 @@ static int proc_readfdinfo(struct file *file, struct dir_context *ctx)
                                  proc_fdinfo_instantiate);
 }
 
-static int proc_open_fdinfo(struct inode *inode, struct file *file)
-{
-       int ret = proc_fdinfo_access_allowed(inode);
-
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
 const struct inode_operations proc_fdinfo_inode_operations = {
        .lookup         = proc_lookupfdinfo,
+       .permission     = proc_fdinfo_permission,
        .setattr        = proc_setattr,
 };
 
 const struct file_operations proc_fdinfo_operations = {
-       .open           = proc_open_fdinfo,
        .read           = generic_read_dir,
        .iterate_shared = proc_readfdinfo,
        .llseek         = generic_file_llseek,
index 2ba31b6d68c0771755b373801ae207ee21423965..52f0b75cbce2caa3b010b18f8fcc18d995ea2b0e 100644 (file)
@@ -135,6 +135,7 @@ EXPORT_SYMBOL_GPL(proc_create_net_data);
  * @parent: The parent directory in which to create.
  * @ops: The seq_file ops with which to read the file.
  * @write: The write method with which to 'modify' the file.
+ * @state_size: The size of the per-file private state to allocate.
  * @data: Data for retrieval by pde_data().
  *
  * Create a network namespaced proc file in the @parent directory with the
index 23fbab954c20b62b7b67413763ca777001073d3b..102f48668c352a9d2502e7e58bb1f442129017f2 100644 (file)
@@ -1817,15 +1817,13 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
 }
 
 static void make_uffd_wp_pte(struct vm_area_struct *vma,
-                            unsigned long addr, pte_t *pte)
+                            unsigned long addr, pte_t *pte, pte_t ptent)
 {
-       pte_t ptent = ptep_get(pte);
-
        if (pte_present(ptent)) {
                pte_t old_pte;
 
                old_pte = ptep_modify_prot_start(vma, addr, pte);
-               ptent = pte_mkuffd_wp(ptent);
+               ptent = pte_mkuffd_wp(old_pte);
                ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
        } else if (is_swap_pte(ptent)) {
                ptent = pte_swp_mkuffd_wp(ptent);
@@ -2175,9 +2173,12 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
        if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
                /* Fast path for performing exclusive WP */
                for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
-                       if (pte_uffd_wp(ptep_get(pte)))
+                       pte_t ptent = ptep_get(pte);
+
+                       if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
+                           pte_swp_uffd_wp_any(ptent))
                                continue;
-                       make_uffd_wp_pte(vma, addr, pte);
+                       make_uffd_wp_pte(vma, addr, pte, ptent);
                        if (!flush_end)
                                start = addr;
                        flush_end = addr + PAGE_SIZE;
@@ -2190,8 +2191,10 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
            p->arg.return_mask == PAGE_IS_WRITTEN) {
                for (addr = start; addr < end; pte++, addr += PAGE_SIZE) {
                        unsigned long next = addr + PAGE_SIZE;
+                       pte_t ptent = ptep_get(pte);
 
-                       if (pte_uffd_wp(ptep_get(pte)))
+                       if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
+                           pte_swp_uffd_wp_any(ptent))
                                continue;
                        ret = pagemap_scan_output(p->cur_vma_category | PAGE_IS_WRITTEN,
                                                  p, addr, &next);
@@ -2199,7 +2202,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
                                break;
                        if (~p->arg.flags & PM_SCAN_WP_MATCHING)
                                continue;
-                       make_uffd_wp_pte(vma, addr, pte);
+                       make_uffd_wp_pte(vma, addr, pte, ptent);
                        if (!flush_end)
                                start = addr;
                        flush_end = next;
@@ -2208,8 +2211,9 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
        }
 
        for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
+               pte_t ptent = ptep_get(pte);
                unsigned long categories = p->cur_vma_category |
-                                          pagemap_page_category(p, vma, addr, ptep_get(pte));
+                                          pagemap_page_category(p, vma, addr, ptent);
                unsigned long next = addr + PAGE_SIZE;
 
                if (!pagemap_scan_is_interesting_page(categories, p))
@@ -2224,7 +2228,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
                if (~categories & PAGE_IS_WRITTEN)
                        continue;
 
-               make_uffd_wp_pte(vma, addr, pte);
+               make_uffd_wp_pte(vma, addr, pte, ptent);
                if (!flush_end)
                        start = addr;
                flush_end = next;
index 405913f4faff99538beab737ee0887931a607b6b..d62fbef838b6817e8c9e12cc5ca19dc41f27342a 100644 (file)
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
 #include <linux/statfs.h>
-#include <linux/parser.h>
 #include <linux/seq_file.h>
-#include <linux/mount.h>
 #include <linux/crc32.h>
 #include <linux/mpage.h>
+#include <linux/fs_parser.h>
+#include <linux/fs_context.h>
 #include "qnx6.h"
 
 static const struct super_operations qnx6_sops;
@@ -31,7 +31,7 @@ static const struct super_operations qnx6_sops;
 static void qnx6_put_super(struct super_block *sb);
 static struct inode *qnx6_alloc_inode(struct super_block *sb);
 static void qnx6_free_inode(struct inode *inode);
-static int qnx6_remount(struct super_block *sb, int *flags, char *data);
+static int qnx6_reconfigure(struct fs_context *fc);
 static int qnx6_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int qnx6_show_options(struct seq_file *seq, struct dentry *root);
 
@@ -40,7 +40,6 @@ static const struct super_operations qnx6_sops = {
        .free_inode     = qnx6_free_inode,
        .put_super      = qnx6_put_super,
        .statfs         = qnx6_statfs,
-       .remount_fs     = qnx6_remount,
        .show_options   = qnx6_show_options,
 };
 
@@ -54,10 +53,12 @@ static int qnx6_show_options(struct seq_file *seq, struct dentry *root)
        return 0;
 }
 
-static int qnx6_remount(struct super_block *sb, int *flags, char *data)
+static int qnx6_reconfigure(struct fs_context *fc)
 {
+       struct super_block *sb = fc->root->d_sb;
+
        sync_filesystem(sb);
-       *flags |= SB_RDONLY;
+       fc->sb_flags |= SB_RDONLY;
        return 0;
 }
 
@@ -218,39 +219,36 @@ void qnx6_superblock_debug(struct qnx6_super_block *sb, struct super_block *s)
 #endif
 
 enum {
-       Opt_mmifs,
-       Opt_err
+       Opt_mmifs
+};
+
+struct qnx6_context {
+       unsigned long s_mount_opts;
 };
 
-static const match_table_t tokens = {
-       {Opt_mmifs, "mmi_fs"},
-       {Opt_err, NULL}
+static const struct fs_parameter_spec qnx6_param_spec[] = {
+       fsparam_flag    ("mmi_fs",      Opt_mmifs),
+       {}
 };
 
-static int qnx6_parse_options(char *options, struct super_block *sb)
+static int qnx6_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
-       char *p;
-       struct qnx6_sb_info *sbi = QNX6_SB(sb);
-       substring_t args[MAX_OPT_ARGS];
-
-       if (!options)
-               return 1;
-
-       while ((p = strsep(&options, ",")) != NULL) {
-               int token;
-               if (!*p)
-                       continue;
-
-               token = match_token(p, tokens, args);
-               switch (token) {
-               case Opt_mmifs:
-                       set_opt(sbi->s_mount_opt, MMI_FS);
-                       break;
-               default:
-                       return 0;
-               }
+       struct qnx6_context *ctx = fc->fs_private;
+       struct fs_parse_result result;
+       int opt;
+
+       opt = fs_parse(fc, qnx6_param_spec, param, &result);
+       if (opt < 0)
+               return opt;
+
+       switch (opt) {
+       case Opt_mmifs:
+               ctx->s_mount_opts |= QNX6_MOUNT_MMI_FS;
+               break;
+       default:
+               return -EINVAL;
        }
-       return 1;
+       return 0;
 }
 
 static struct buffer_head *qnx6_check_first_superblock(struct super_block *s,
@@ -293,22 +291,25 @@ static struct buffer_head *qnx6_check_first_superblock(struct super_block *s,
 static struct inode *qnx6_private_inode(struct super_block *s,
                                        struct qnx6_root_node *p);
 
-static int qnx6_fill_super(struct super_block *s, void *data, int silent)
+static int qnx6_fill_super(struct super_block *s, struct fs_context *fc)
 {
        struct buffer_head *bh1 = NULL, *bh2 = NULL;
        struct qnx6_super_block *sb1 = NULL, *sb2 = NULL;
        struct qnx6_sb_info *sbi;
+       struct qnx6_context *ctx = fc->fs_private;
        struct inode *root;
        const char *errmsg;
        struct qnx6_sb_info *qs;
        int ret = -EINVAL;
        u64 offset;
        int bootblock_offset = QNX6_BOOTBLOCK_SIZE;
+       int silent = fc->sb_flags & SB_SILENT;
 
        qs = kzalloc(sizeof(struct qnx6_sb_info), GFP_KERNEL);
        if (!qs)
                return -ENOMEM;
        s->s_fs_info = qs;
+       qs->s_mount_opt = ctx->s_mount_opts;
 
        /* Superblock always is 512 Byte long */
        if (!sb_set_blocksize(s, QNX6_SUPERBLOCK_SIZE)) {
@@ -316,12 +317,7 @@ static int qnx6_fill_super(struct super_block *s, void *data, int silent)
                goto outnobh;
        }
 
-       /* parse the mount-options */
-       if (!qnx6_parse_options((char *) data, s)) {
-               pr_err("invalid mount options.\n");
-               goto outnobh;
-       }
-       if (test_opt(s, MMI_FS)) {
+       if (qs->s_mount_opt == QNX6_MOUNT_MMI_FS) {
                sb1 = qnx6_mmi_fill_super(s, silent);
                if (sb1)
                        goto mmi_success;
@@ -632,18 +628,43 @@ static void destroy_inodecache(void)
        kmem_cache_destroy(qnx6_inode_cachep);
 }
 
-static struct dentry *qnx6_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *data)
+static int qnx6_get_tree(struct fs_context *fc)
+{
+       return get_tree_bdev(fc, qnx6_fill_super);
+}
+
+static void qnx6_free_fc(struct fs_context *fc)
 {
-       return mount_bdev(fs_type, flags, dev_name, data, qnx6_fill_super);
+       kfree(fc->fs_private);
+}
+
+static const struct fs_context_operations qnx6_context_ops = {
+       .parse_param    = qnx6_parse_param,
+       .get_tree       = qnx6_get_tree,
+       .reconfigure    = qnx6_reconfigure,
+       .free           = qnx6_free_fc,
+};
+
+static int qnx6_init_fs_context(struct fs_context *fc)
+{
+       struct qnx6_context *ctx;
+
+       ctx = kzalloc(sizeof(struct qnx6_context), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+       fc->ops = &qnx6_context_ops;
+       fc->fs_private = ctx;
+
+       return 0;
 }
 
 static struct file_system_type qnx6_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "qnx6",
-       .mount          = qnx6_mount,
-       .kill_sb        = kill_block_super,
-       .fs_flags       = FS_REQUIRES_DEV,
+       .owner                  = THIS_MODULE,
+       .name                   = "qnx6",
+       .kill_sb                = kill_block_super,
+       .fs_flags               = FS_REQUIRES_DEV,
+       .init_fs_context        = qnx6_init_fs_context,
+       .parameters             = qnx6_param_spec,
 };
 MODULE_ALIAS_FS("qnx6");
 
index d4c036e82b6c38cf706e463363d16d78e4dd3fdf..2115d1f40bd5c6147b0ba4ab910fc61459e07119 100644 (file)
@@ -1685,7 +1685,7 @@ int generic_write_checks_count(struct kiocb *iocb, loff_t *count)
 
        if ((iocb->ki_flags & IOCB_NOWAIT) &&
            !((iocb->ki_flags & IOCB_DIRECT) ||
-             (file->f_mode & FMODE_BUF_WASYNC)))
+             (file->f_op->fop_flags & FOP_BUFFER_WASYNC)))
                return -EINVAL;
 
        return generic_write_check_limits(iocb->ki_filp, iocb->ki_pos, count);
index f5fdaf3b157286d20c5c9c252df7d0885723e2e4..e676c8b0cf5d8af861724222c006c67d908c2849 100644 (file)
@@ -669,18 +669,11 @@ void seq_putc(struct seq_file *m, char c)
 }
 EXPORT_SYMBOL(seq_putc);
 
-void seq_puts(struct seq_file *m, const char *s)
+void __seq_puts(struct seq_file *m, const char *s)
 {
-       int len = strlen(s);
-
-       if (m->count + len >= m->size) {
-               seq_set_overflow(m);
-               return;
-       }
-       memcpy(m->buf + m->count, s, len);
-       m->count += len;
+       seq_write(m, s, strlen(s));
 }
-EXPORT_SYMBOL(seq_puts);
+EXPORT_SYMBOL(__seq_puts);
 
 /**
  * seq_put_decimal_ull_width - A helper routine for putting decimal numbers
index e20d1484c6633310a64f52af69035248e77390e4..4a5614442dbfa733ff2dc9fa704532e8b5cc147c 100644 (file)
@@ -68,8 +68,7 @@ static __poll_t signalfd_poll(struct file *file, poll_table *wait)
 /*
  * Copied from copy_siginfo_to_user() in kernel/signal.c
  */
-static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
-                            kernel_siginfo_t const *kinfo)
+static int signalfd_copyinfo(struct iov_iter *to, kernel_siginfo_t const *kinfo)
 {
        struct signalfd_siginfo new;
 
@@ -146,10 +145,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
                break;
        }
 
-       if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
+       if (!copy_to_iter_full(&new, sizeof(struct signalfd_siginfo), to))
                return -EFAULT;
 
-       return sizeof(*uinfo);
+       return sizeof(struct signalfd_siginfo);
 }
 
 static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info,
@@ -199,28 +198,27 @@ static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info
  * error code. The "count" parameter must be at least the size of a
  * "struct signalfd_siginfo".
  */
-static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
-                            loff_t *ppos)
+static ssize_t signalfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
+       struct file *file = iocb->ki_filp;
        struct signalfd_ctx *ctx = file->private_data;
-       struct signalfd_siginfo __user *siginfo;
-       int nonblock = file->f_flags & O_NONBLOCK;
+       size_t count = iov_iter_count(to);
        ssize_t ret, total = 0;
        kernel_siginfo_t info;
+       bool nonblock;
 
        count /= sizeof(struct signalfd_siginfo);
        if (!count)
                return -EINVAL;
 
-       siginfo = (struct signalfd_siginfo __user *) buf;
+       nonblock = file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT;
        do {
                ret = signalfd_dequeue(ctx, &info, nonblock);
                if (unlikely(ret <= 0))
                        break;
-               ret = signalfd_copyinfo(siginfo, &info);
+               ret = signalfd_copyinfo(to, &info);
                if (ret < 0)
                        break;
-               siginfo++;
                total += ret;
                nonblock = 1;
        } while (--count);
@@ -246,7 +244,7 @@ static const struct file_operations signalfd_fops = {
 #endif
        .release        = signalfd_release,
        .poll           = signalfd_poll,
-       .read           = signalfd_read,
+       .read_iter      = signalfd_read_iter,
        .llseek         = noop_llseek,
 };
 
@@ -265,20 +263,34 @@ static int do_signalfd4(int ufd, sigset_t *mask, int flags)
        signotset(mask);
 
        if (ufd == -1) {
+               struct file *file;
+
                ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
                if (!ctx)
                        return -ENOMEM;
 
                ctx->sigmask = *mask;
 
+               ufd = get_unused_fd_flags(flags & O_CLOEXEC);
+               if (ufd < 0) {
+                       kfree(ctx);
+                       return ufd;
+               }
+
+               file = anon_inode_getfile("[signalfd]", &signalfd_fops, ctx,
+                                      O_RDWR | (flags & O_NONBLOCK));
+               if (IS_ERR(file)) {
+                       put_unused_fd(ufd);
+                       kfree(ctx);
+                       return ufd;
+               }
+               file->f_mode |= FMODE_NOWAIT;
+
                /*
                 * When we call this, the initialization must be complete, since
                 * anon_inode_getfd() will install the fd.
                 */
-               ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
-                                      O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
-               if (ufd < 0)
-                       kfree(ctx);
+               fd_install(ufd, file);
        } else {
                struct fd f = fdget(ufd);
                if (!f.file)
index 2927bd174a887f2e1b91d7a37f0be23d8e5f4d60..2517dc2423869bc3107d1cdef8bd61a6d79e92de 100644 (file)
@@ -2,6 +2,7 @@
 config CIFS
        tristate "SMB3 and CIFS support (advanced network filesystem)"
        depends on INET
+       select NETFS_SUPPORT
        select NLS
        select NLS_UCS2_UTILS
        select CRYPTO
index 39277c37185cac3327c0f002849b1f5fc621cd05..ec5b639f421a27e46c894ff977237eb4c994942f 100644 (file)
@@ -371,9 +371,13 @@ static struct kmem_cache *cifs_inode_cachep;
 static struct kmem_cache *cifs_req_cachep;
 static struct kmem_cache *cifs_mid_cachep;
 static struct kmem_cache *cifs_sm_req_cachep;
+static struct kmem_cache *cifs_io_request_cachep;
+static struct kmem_cache *cifs_io_subrequest_cachep;
 mempool_t *cifs_sm_req_poolp;
 mempool_t *cifs_req_poolp;
 mempool_t *cifs_mid_poolp;
+mempool_t cifs_io_request_pool;
+mempool_t cifs_io_subrequest_pool;
 
 static struct inode *
 cifs_alloc_inode(struct super_block *sb)
@@ -986,61 +990,6 @@ out:
        return root;
 }
 
-
-static ssize_t
-cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
-{
-       ssize_t rc;
-       struct inode *inode = file_inode(iocb->ki_filp);
-
-       if (iocb->ki_flags & IOCB_DIRECT)
-               return cifs_user_readv(iocb, iter);
-
-       rc = cifs_revalidate_mapping(inode);
-       if (rc)
-               return rc;
-
-       return generic_file_read_iter(iocb, iter);
-}
-
-static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
-{
-       struct inode *inode = file_inode(iocb->ki_filp);
-       struct cifsInodeInfo *cinode = CIFS_I(inode);
-       ssize_t written;
-       int rc;
-
-       if (iocb->ki_filp->f_flags & O_DIRECT) {
-               written = cifs_user_writev(iocb, from);
-               if (written > 0 && CIFS_CACHE_READ(cinode)) {
-                       cifs_zap_mapping(inode);
-                       cifs_dbg(FYI,
-                                "Set no oplock for inode=%p after a write operation\n",
-                                inode);
-                       cinode->oplock = 0;
-               }
-               return written;
-       }
-
-       written = cifs_get_writer(cinode);
-       if (written)
-               return written;
-
-       written = generic_file_write_iter(iocb, from);
-
-       if (CIFS_CACHE_WRITE(CIFS_I(inode)))
-               goto out;
-
-       rc = filemap_fdatawrite(inode->i_mapping);
-       if (rc)
-               cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
-                        rc, inode);
-
-out:
-       cifs_put_writer(cinode);
-       return written;
-}
-
 static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
 {
        struct cifsFileInfo *cfile = file->private_data;
@@ -1342,6 +1291,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
        rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false);
        if (rc)
                goto unlock;
+       if (fend > target_cifsi->netfs.zero_point)
+               target_cifsi->netfs.zero_point = fend + 1;
 
        /* Discard all the folios that overlap the destination region. */
        cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend);
@@ -1360,6 +1311,8 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
                        fscache_resize_cookie(cifs_inode_cookie(target_inode),
                                              new_size);
                }
+               if (rc == 0 && new_size > target_cifsi->netfs.zero_point)
+                       target_cifsi->netfs.zero_point = new_size;
        }
 
        /* force revalidate of size and timestamps of target file now
@@ -1451,6 +1404,8 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
        rc = cifs_flush_folio(target_inode, destend, &fstart, &fend, false);
        if (rc)
                goto unlock;
+       if (fend > target_cifsi->netfs.zero_point)
+               target_cifsi->netfs.zero_point = fend + 1;
 
        /* Discard all the folios that overlap the destination region. */
        truncate_inode_pages_range(&target_inode->i_data, fstart, fend);
@@ -1567,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = {
 };
 
 const struct file_operations cifs_file_direct_ops = {
-       .read_iter = cifs_direct_readv,
-       .write_iter = cifs_direct_writev,
+       .read_iter = netfs_unbuffered_read_iter,
+       .write_iter = netfs_file_write_iter,
        .open = cifs_open,
        .release = cifs_close,
        .lock = cifs_lock,
@@ -1623,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
 };
 
 const struct file_operations cifs_file_direct_nobrl_ops = {
-       .read_iter = cifs_direct_readv,
-       .write_iter = cifs_direct_writev,
+       .read_iter = netfs_unbuffered_read_iter,
+       .write_iter = netfs_file_write_iter,
        .open = cifs_open,
        .release = cifs_close,
        .fsync = cifs_fsync,
@@ -1799,6 +1754,48 @@ static void destroy_mids(void)
        kmem_cache_destroy(cifs_mid_cachep);
 }
 
+static int cifs_init_netfs(void)
+{
+       cifs_io_request_cachep =
+               kmem_cache_create("cifs_io_request",
+                                 sizeof(struct cifs_io_request), 0,
+                                 SLAB_HWCACHE_ALIGN, NULL);
+       if (!cifs_io_request_cachep)
+               goto nomem_req;
+
+       if (mempool_init_slab_pool(&cifs_io_request_pool, 100, cifs_io_request_cachep) < 0)
+               goto nomem_reqpool;
+
+       cifs_io_subrequest_cachep =
+               kmem_cache_create("cifs_io_subrequest",
+                                 sizeof(struct cifs_io_subrequest), 0,
+                                 SLAB_HWCACHE_ALIGN, NULL);
+       if (!cifs_io_subrequest_cachep)
+               goto nomem_subreq;
+
+       if (mempool_init_slab_pool(&cifs_io_subrequest_pool, 100, cifs_io_subrequest_cachep) < 0)
+               goto nomem_subreqpool;
+
+       return 0;
+
+nomem_subreqpool:
+       kmem_cache_destroy(cifs_io_subrequest_cachep);
+nomem_subreq:
+       mempool_destroy(&cifs_io_request_pool);
+nomem_reqpool:
+       kmem_cache_destroy(cifs_io_request_cachep);
+nomem_req:
+       return -ENOMEM;
+}
+
+static void cifs_destroy_netfs(void)
+{
+       mempool_exit(&cifs_io_subrequest_pool);
+       kmem_cache_destroy(cifs_io_subrequest_cachep);
+       mempool_exit(&cifs_io_request_pool);
+       kmem_cache_destroy(cifs_io_request_cachep);
+}
+
 static int __init
 init_cifs(void)
 {
@@ -1903,10 +1900,14 @@ init_cifs(void)
        if (rc)
                goto out_destroy_deferredclose_wq;
 
-       rc = init_mids();
+       rc = cifs_init_netfs();
        if (rc)
                goto out_destroy_inodecache;
 
+       rc = init_mids();
+       if (rc)
+               goto out_destroy_netfs;
+
        rc = cifs_init_request_bufs();
        if (rc)
                goto out_destroy_mids;
@@ -1961,6 +1962,8 @@ out_destroy_request_bufs:
        cifs_destroy_request_bufs();
 out_destroy_mids:
        destroy_mids();
+out_destroy_netfs:
+       cifs_destroy_netfs();
 out_destroy_inodecache:
        cifs_destroy_inodecache();
 out_destroy_deferredclose_wq:
@@ -1999,6 +2002,7 @@ exit_cifs(void)
 #endif
        cifs_destroy_request_bufs();
        destroy_mids();
+       cifs_destroy_netfs();
        cifs_destroy_inodecache();
        destroy_workqueue(deferredclose_wq);
        destroy_workqueue(cifsoplockd_wq);
index ca55d01117c8d349f078b51ddfccd5d6f8c2bd05..87310f05d39765fa8fb692a0b13061febb8edd87 100644 (file)
@@ -69,7 +69,6 @@ extern int cifs_revalidate_file_attr(struct file *filp);
 extern int cifs_revalidate_dentry_attr(struct dentry *);
 extern int cifs_revalidate_file(struct file *filp);
 extern int cifs_revalidate_dentry(struct dentry *);
-extern int cifs_invalidate_mapping(struct inode *inode);
 extern int cifs_revalidate_mapping(struct inode *inode);
 extern int cifs_zap_mapping(struct inode *inode);
 extern int cifs_getattr(struct mnt_idmap *, const struct path *,
@@ -85,6 +84,7 @@ extern const struct inode_operations cifs_namespace_inode_operations;
 
 
 /* Functions related to files and directories */
+extern const struct netfs_request_ops cifs_req_ops;
 extern const struct file_operations cifs_file_ops;
 extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
 extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
@@ -94,12 +94,10 @@ extern const struct file_operations cifs_file_strict_nobrl_ops;
 extern int cifs_open(struct inode *inode, struct file *file);
 extern int cifs_close(struct inode *inode, struct file *file);
 extern int cifs_closedir(struct inode *inode, struct file *file);
-extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
-extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
 extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
-extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
-extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
 extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
+ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
+ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
 extern int cifs_flock(struct file *pfile, int cmd, struct file_lock *plock);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, loff_t, loff_t, int);
@@ -110,9 +108,6 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
 extern const struct file_operations cifs_dir_ops;
 extern int cifs_dir_open(struct inode *inode, struct file *file);
 extern int cifs_readdir(struct file *file, struct dir_context *ctx);
-extern void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len);
-extern void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len);
-extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len);
 
 /* Functions related to dir entries */
 extern const struct dentry_operations cifs_dentry_ops;
index 6ff35570db813a533ef9221fad6a7aea99e6d1d2..73482734a8d8e9523940b8d0e791320edc6b6863 100644 (file)
@@ -268,8 +268,7 @@ struct dfs_info3_param;
 struct cifs_fattr;
 struct smb3_fs_context;
 struct cifs_fid;
-struct cifs_readdata;
-struct cifs_writedata;
+struct cifs_io_subrequest;
 struct cifs_io_parms;
 struct cifs_search_info;
 struct cifsInodeInfo;
@@ -450,10 +449,9 @@ struct smb_version_operations {
        /* send a flush request to the server */
        int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
        /* async read from the server */
-       int (*async_readv)(struct cifs_readdata *);
+       int (*async_readv)(struct cifs_io_subrequest *);
        /* async write to the server */
-       int (*async_writev)(struct cifs_writedata *,
-                           void (*release)(struct kref *));
+       void (*async_writev)(struct cifs_io_subrequest *);
        /* sync read from the server */
        int (*sync_read)(const unsigned int, struct cifs_fid *,
                         struct cifs_io_parms *, unsigned int *, char **,
@@ -548,8 +546,8 @@ struct smb_version_operations {
        /* writepages retry size */
        unsigned int (*wp_retry_size)(struct inode *);
        /* get mtu credits */
-       int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int,
-                               unsigned int *, struct cifs_credits *);
+       int (*wait_mtu_credits)(struct TCP_Server_Info *, size_t,
+                               size_t *, struct cifs_credits *);
        /* adjust previously taken mtu credits to request size */
        int (*adjust_credits)(struct TCP_Server_Info *server,
                              struct cifs_credits *credits,
@@ -883,11 +881,12 @@ add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits,
 
 static inline void
 add_credits_and_wake_if(struct TCP_Server_Info *server,
-                       const struct cifs_credits *credits, const int optype)
+                       struct cifs_credits *credits, const int optype)
 {
        if (credits->value) {
                server->ops->add_credits(server, credits, optype);
                wake_up(&server->request_q);
+               credits->value = 0;
        }
 }
 
@@ -1492,50 +1491,30 @@ struct cifs_aio_ctx {
        bool                    direct_io;
 };
 
-/* asynchronous read support */
-struct cifs_readdata {
-       struct kref                     refcount;
-       struct list_head                list;
-       struct completion               done;
+struct cifs_io_request {
+       struct netfs_io_request         rreq;
        struct cifsFileInfo             *cfile;
-       struct address_space            *mapping;
-       struct cifs_aio_ctx             *ctx;
-       __u64                           offset;
-       ssize_t                         got_bytes;
-       unsigned int                    bytes;
-       pid_t                           pid;
-       int                             result;
-       struct work_struct              work;
-       struct iov_iter                 iter;
-       struct kvec                     iov[2];
-       struct TCP_Server_Info          *server;
-#ifdef CONFIG_CIFS_SMB_DIRECT
-       struct smbd_mr                  *mr;
-#endif
-       struct cifs_credits             credits;
 };
 
-/* asynchronous write support */
-struct cifs_writedata {
-       struct kref                     refcount;
-       struct list_head                list;
-       struct completion               done;
-       enum writeback_sync_modes       sync_mode;
-       struct work_struct              work;
-       struct cifsFileInfo             *cfile;
-       struct cifs_aio_ctx             *ctx;
-       struct iov_iter                 iter;
-       struct bio_vec                  *bv;
-       __u64                           offset;
+/* asynchronous read support */
+struct cifs_io_subrequest {
+       union {
+               struct netfs_io_subrequest subreq;
+               struct netfs_io_request *rreq;
+               struct cifs_io_request *req;
+       };
+       ssize_t                         got_bytes;
        pid_t                           pid;
-       unsigned int                    bytes;
+       unsigned int                    xid;
        int                             result;
+       bool                            have_xid;
+       bool                            replay;
+       struct kvec                     iov[2];
        struct TCP_Server_Info          *server;
 #ifdef CONFIG_CIFS_SMB_DIRECT
        struct smbd_mr                  *mr;
 #endif
        struct cifs_credits             credits;
-       bool                            replay;
 };
 
 /*
@@ -2016,6 +1995,7 @@ require use of the stronger protocol */
  *                             ->chans_need_reconnect
  *                             ->chans_in_reconnect
  * cifs_tcon->tc_lock          (anything that is not protected by another lock and can change)
+ * inode->i_rwsem, taken by fs/netfs/locking.c e.g. should be taken before cifsInodeInfo locks
  * cifsInodeInfo->open_file_lock       cifsInodeInfo->openFileList     cifs_alloc_inode
  * cifsInodeInfo->writers_lock cifsInodeInfo->writers          cifsInodeInfo_alloc
  * cifsInodeInfo->lock_sem     cifsInodeInfo->llist            cifs_init_once
@@ -2115,6 +2095,8 @@ extern __u32 cifs_lock_secret;
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
+extern mempool_t cifs_io_request_pool;
+extern mempool_t cifs_io_subrequest_pool;
 
 /* Operations for different SMB versions */
 #define SMB1_VERSION_STRING    "1.0"
index fbc358c09da3b1d7ffc495d0c461e32509f95c1c..c15bb5ee7eb7d6787f5138499591071169008bda 100644 (file)
@@ -121,7 +121,7 @@ extern struct mid_q_entry *cifs_setup_async_request(struct TCP_Server_Info *,
 extern int cifs_check_receive(struct mid_q_entry *mid,
                        struct TCP_Server_Info *server, bool log_error);
 extern int cifs_wait_mtu_credits(struct TCP_Server_Info *server,
-                                unsigned int size, unsigned int *num,
+                                size_t size, size_t *num,
                                 struct cifs_credits *credits);
 extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
                        struct kvec *, int /* nvec to send */,
@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
                                   bool from_readdir);
 extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
                            unsigned int bytes_written);
+void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
+                                     bool was_async);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
 extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
                                  int flags,
@@ -599,15 +601,11 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
 extern struct cifs_ses *
 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
 
-void cifs_readdata_release(struct kref *refcount);
-int cifs_async_readv(struct cifs_readdata *rdata);
+int cifs_async_readv(struct cifs_io_subrequest *rdata);
 int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
 
-int cifs_async_writev(struct cifs_writedata *wdata,
-                     void (*release)(struct kref *kref));
+void cifs_async_writev(struct cifs_io_subrequest *wdata);
 void cifs_writev_complete(struct work_struct *work);
-struct cifs_writedata *cifs_writedata_alloc(work_func_t complete);
-void cifs_writedata_release(struct kref *refcount);
 int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
                          struct cifs_sb_info *cifs_sb,
                          const unsigned char *path, char *pbuf,
index 23b5709ddc311c7366e33505528711363d151a14..25e9ab947c1715a0dad0f65561cb051d30fb7345 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/swap.h>
 #include <linux/task_io_accounting_ops.h>
 #include <linux/uaccess.h>
+#include <linux/netfs.h>
+#include <trace/events/netfs.h>
 #include "cifspdu.h"
 #include "cifsfs.h"
 #include "cifsglob.h"
@@ -1262,18 +1264,17 @@ openRetry:
 static void
 cifs_readv_callback(struct mid_q_entry *mid)
 {
-       struct cifs_readdata *rdata = mid->callback_data;
-       struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+       struct cifs_io_subrequest *rdata = mid->callback_data;
+       struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
        struct TCP_Server_Info *server = tcon->ses->server;
        struct smb_rqst rqst = { .rq_iov = rdata->iov,
                                 .rq_nvec = 2,
-                                .rq_iter_size = iov_iter_count(&rdata->iter),
-                                .rq_iter = rdata->iter };
+                                .rq_iter = rdata->subreq.io_iter };
        struct cifs_credits credits = { .value = 1, .instance = 0 };
 
-       cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
+       cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
                 __func__, mid->mid, mid->mid_state, rdata->result,
-                rdata->bytes);
+                rdata->subreq.len);
 
        switch (mid->mid_state) {
        case MID_RESPONSE_RECEIVED:
@@ -1305,30 +1306,36 @@ cifs_readv_callback(struct mid_q_entry *mid)
                rdata->result = -EIO;
        }
 
-       queue_work(cifsiod_wq, &rdata->work);
+       if (rdata->result == 0 || rdata->result == -EAGAIN)
+               iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
+       rdata->credits.value = 0;
+       netfs_subreq_terminated(&rdata->subreq,
+                               (rdata->result == 0 || rdata->result == -EAGAIN) ?
+                               rdata->got_bytes : rdata->result,
+                               false);
        release_mid(mid);
        add_credits(server, &credits, 0);
 }
 
 /* cifs_async_readv - send an async write, and set up mid to handle result */
 int
-cifs_async_readv(struct cifs_readdata *rdata)
+cifs_async_readv(struct cifs_io_subrequest *rdata)
 {
        int rc;
        READ_REQ *smb = NULL;
        int wct;
-       struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
        struct smb_rqst rqst = { .rq_iov = rdata->iov,
                                 .rq_nvec = 2 };
 
-       cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
-                __func__, rdata->offset, rdata->bytes);
+       cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
+                __func__, rdata->subreq.start, rdata->subreq.len);
 
        if (tcon->ses->capabilities & CAP_LARGE_FILES)
                wct = 12;
        else {
                wct = 10; /* old style read */
-               if ((rdata->offset >> 32) > 0)  {
+               if ((rdata->subreq.start >> 32) > 0)  {
                        /* can not handle this big offset for old */
                        return -EIO;
                }
@@ -1342,13 +1349,13 @@ cifs_async_readv(struct cifs_readdata *rdata)
        smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
 
        smb->AndXCommand = 0xFF;        /* none */
-       smb->Fid = rdata->cfile->fid.netfid;
-       smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
+       smb->Fid = rdata->req->cfile->fid.netfid;
+       smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
        if (wct == 12)
-               smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
+               smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
        smb->Remaining = 0;
-       smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
-       smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
+       smb->MaxCount = cpu_to_le16(rdata->subreq.len & 0xFFFF);
+       smb->MaxCountHigh = cpu_to_le32(rdata->subreq.len >> 16);
        if (wct == 12)
                smb->ByteCount = 0;
        else {
@@ -1364,15 +1371,11 @@ cifs_async_readv(struct cifs_readdata *rdata)
        rdata->iov[1].iov_base = (char *)smb + 4;
        rdata->iov[1].iov_len = get_rfc1002_length(smb);
 
-       kref_get(&rdata->refcount);
        rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
                             cifs_readv_callback, NULL, rdata, 0, NULL);
 
        if (rc == 0)
                cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
-       else
-               kref_put(&rdata->refcount, cifs_readdata_release);
-
        cifs_small_buf_release(smb);
        return rc;
 }
@@ -1615,16 +1618,17 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
 static void
 cifs_writev_callback(struct mid_q_entry *mid)
 {
-       struct cifs_writedata *wdata = mid->callback_data;
-       struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
-       unsigned int written;
+       struct cifs_io_subrequest *wdata = mid->callback_data;
+       struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
        WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
        struct cifs_credits credits = { .value = 1, .instance = 0 };
+       ssize_t result;
+       size_t written;
 
        switch (mid->mid_state) {
        case MID_RESPONSE_RECEIVED:
-               wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
-               if (wdata->result != 0)
+               result = cifs_check_receive(mid, tcon->ses->server, 0);
+               if (result != 0)
                        break;
 
                written = le16_to_cpu(smb->CountHigh);
@@ -1636,37 +1640,37 @@ cifs_writev_callback(struct mid_q_entry *mid)
                 * client. OS/2 servers are known to set incorrect
                 * CountHigh values.
                 */
-               if (written > wdata->bytes)
+               if (written > wdata->subreq.len)
                        written &= 0xFFFF;
 
-               if (written < wdata->bytes)
-                       wdata->result = -ENOSPC;
+               if (written < wdata->subreq.len)
+                       result = -ENOSPC;
                else
-                       wdata->bytes = written;
+                       result = written;
                break;
        case MID_REQUEST_SUBMITTED:
        case MID_RETRY_NEEDED:
-               wdata->result = -EAGAIN;
+               result = -EAGAIN;
                break;
        default:
-               wdata->result = -EIO;
+               result = -EIO;
                break;
        }
 
-       queue_work(cifsiod_wq, &wdata->work);
+       wdata->credits.value = 0;
+       cifs_write_subrequest_terminated(wdata, result, true);
        release_mid(mid);
        add_credits(tcon->ses->server, &credits, 0);
 }
 
 /* cifs_async_writev - send an async write, and set up mid to handle result */
-int
-cifs_async_writev(struct cifs_writedata *wdata,
-                 void (*release)(struct kref *kref))
+void
+cifs_async_writev(struct cifs_io_subrequest *wdata)
 {
        int rc = -EACCES;
        WRITE_REQ *smb = NULL;
        int wct;
-       struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
        struct kvec iov[2];
        struct smb_rqst rqst = { };
 
@@ -1674,9 +1678,10 @@ cifs_async_writev(struct cifs_writedata *wdata,
                wct = 14;
        } else {
                wct = 12;
-               if (wdata->offset >> 32 > 0) {
+               if (wdata->subreq.start >> 32 > 0) {
                        /* can not handle big offset for old srv */
-                       return -EIO;
+                       rc = -EIO;
+                       goto out;
                }
        }
 
@@ -1688,10 +1693,10 @@ cifs_async_writev(struct cifs_writedata *wdata,
        smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
 
        smb->AndXCommand = 0xFF;        /* none */
-       smb->Fid = wdata->cfile->fid.netfid;
-       smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
+       smb->Fid = wdata->req->cfile->fid.netfid;
+       smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
        if (wct == 14)
-               smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
+               smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
        smb->Reserved = 0xFFFFFFFF;
        smb->WriteMode = 0;
        smb->Remaining = 0;
@@ -1707,39 +1712,40 @@ cifs_async_writev(struct cifs_writedata *wdata,
 
        rqst.rq_iov = iov;
        rqst.rq_nvec = 2;
-       rqst.rq_iter = wdata->iter;
-       rqst.rq_iter_size = iov_iter_count(&wdata->iter);
+       rqst.rq_iter = wdata->subreq.io_iter;
+       rqst.rq_iter_size = iov_iter_count(&wdata->subreq.io_iter);
 
-       cifs_dbg(FYI, "async write at %llu %u bytes\n",
-                wdata->offset, wdata->bytes);
+       cifs_dbg(FYI, "async write at %llu %zu bytes\n",
+                wdata->subreq.start, wdata->subreq.len);
 
-       smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
-       smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
+       smb->DataLengthLow = cpu_to_le16(wdata->subreq.len & 0xFFFF);
+       smb->DataLengthHigh = cpu_to_le16(wdata->subreq.len >> 16);
 
        if (wct == 14) {
-               inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
-               put_bcc(wdata->bytes + 1, &smb->hdr);
+               inc_rfc1001_len(&smb->hdr, wdata->subreq.len + 1);
+               put_bcc(wdata->subreq.len + 1, &smb->hdr);
        } else {
                /* wct == 12 */
                struct smb_com_writex_req *smbw =
                                (struct smb_com_writex_req *)smb;
-               inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
-               put_bcc(wdata->bytes + 5, &smbw->hdr);
+               inc_rfc1001_len(&smbw->hdr, wdata->subreq.len + 5);
+               put_bcc(wdata->subreq.len + 5, &smbw->hdr);
                iov[1].iov_len += 4; /* pad bigger by four bytes */
        }
 
-       kref_get(&wdata->refcount);
        rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
                             cifs_writev_callback, NULL, wdata, 0, NULL);
-
+       /* Can't touch wdata if rc == 0 */
        if (rc == 0)
                cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
-       else
-               kref_put(&wdata->refcount, release);
 
 async_writev_out:
        cifs_small_buf_release(smb);
-       return rc;
+out:
+       if (rc) {
+               add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+               cifs_write_subrequest_terminated(wdata, rc, false);
+       }
 }
 
 int
index 9be37d0fe724e90af1981c109512a64f01d86a0a..9d38294a7e68002e348ee57a8a005c02d83c0955 100644 (file)
 #include "fs_context.h"
 #include "cifs_ioctl.h"
 #include "cached_dir.h"
+#include <trace/events/netfs.h>
+
+static int cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush);
 
 /*
- * Remove the dirty flags from a span of pages.
+ * Prepare a subrequest to upload to the server.  We need to allocate credits
+ * so that we know the maximum amount of data that we can include in it.
  */
-static void cifs_undirty_folios(struct inode *inode, loff_t start, unsigned int len)
+static void cifs_prepare_write(struct netfs_io_subrequest *subreq)
 {
-       struct address_space *mapping = inode->i_mapping;
-       struct folio *folio;
-       pgoff_t end;
+       struct cifs_io_subrequest *wdata =
+               container_of(subreq, struct cifs_io_subrequest, subreq);
+       struct cifs_io_request *req = wdata->req;
+       struct TCP_Server_Info *server;
+       struct cifsFileInfo *open_file = req->cfile;
+       size_t wsize = req->rreq.wsize;
+       int rc;
 
-       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+       if (!wdata->have_xid) {
+               wdata->xid = get_xid();
+               wdata->have_xid = true;
+       }
 
-       rcu_read_lock();
+       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
+       wdata->server = server;
 
-       end = (start + len - 1) / PAGE_SIZE;
-       xas_for_each_marked(&xas, folio, end, PAGECACHE_TAG_DIRTY) {
-               if (xas_retry(&xas, folio))
-                       continue;
-               xas_pause(&xas);
-               rcu_read_unlock();
-               folio_lock(folio);
-               folio_clear_dirty_for_io(folio);
-               folio_unlock(folio);
-               rcu_read_lock();
+retry:
+       if (open_file->invalidHandle) {
+               rc = cifs_reopen_file(open_file, false);
+               if (rc < 0) {
+                       if (rc == -EAGAIN)
+                               goto retry;
+                       subreq->error = rc;
+                       return netfs_prepare_write_failed(subreq);
+               }
+       }
+
+       rc = server->ops->wait_mtu_credits(server, wsize, &wdata->subreq.max_len,
+                                          &wdata->credits);
+       if (rc < 0) {
+               subreq->error = rc;
+               return netfs_prepare_write_failed(subreq);
        }
 
-       rcu_read_unlock();
+#ifdef CONFIG_CIFS_SMB_DIRECT
+       if (server->smbd_conn)
+               subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+#endif
 }
 
 /*
- * Completion of write to server.
+ * Issue a subrequest to upload to the server.
  */
-void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len)
+static void cifs_issue_write(struct netfs_io_subrequest *subreq)
 {
-       struct address_space *mapping = inode->i_mapping;
-       struct folio *folio;
-       pgoff_t end;
+       struct cifs_io_subrequest *wdata =
+               container_of(subreq, struct cifs_io_subrequest, subreq);
+       struct cifs_sb_info *sbi = CIFS_SB(subreq->rreq->inode->i_sb);
+       int rc;
 
-       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+       if (cifs_forced_shutdown(sbi)) {
+               rc = -EIO;
+               goto fail;
+       }
 
-       if (!len)
-               return;
+       rc = adjust_credits(wdata->server, &wdata->credits, wdata->subreq.len);
+       if (rc)
+               goto fail;
 
-       rcu_read_lock();
+       rc = -EAGAIN;
+       if (wdata->req->cfile->invalidHandle)
+               goto fail;
 
-       end = (start + len - 1) / PAGE_SIZE;
-       xas_for_each(&xas, folio, end) {
-               if (xas_retry(&xas, folio))
-                       continue;
-               if (!folio_test_writeback(folio)) {
-                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
-                                 len, start, folio->index, end);
-                       continue;
-               }
+       wdata->server->ops->async_writev(wdata);
+out:
+       return;
+
+fail:
+       if (rc == -EAGAIN)
+               trace_netfs_sreq(subreq, netfs_sreq_trace_retry);
+       else
+               trace_netfs_sreq(subreq, netfs_sreq_trace_fail);
+       add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+       cifs_write_subrequest_terminated(wdata, rc, false);
+       goto out;
+}
+
+/*
+ * Split the read up according to how many credits we can get for each piece.
+ * It's okay to sleep here if we need to wait for more credit to become
+ * available.
+ *
+ * We also choose the server and allocate an operation ID to be cleaned up
+ * later.
+ */
+static bool cifs_clamp_length(struct netfs_io_subrequest *subreq)
+{
+       struct netfs_io_request *rreq = subreq->rreq;
+       struct TCP_Server_Info *server;
+       struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq);
+       struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
+       size_t rsize = 0;
+       int rc;
+
+       rdata->xid = get_xid();
+       rdata->have_xid = true;
 
-               folio_detach_private(folio);
-               folio_end_writeback(folio);
+       server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses);
+       rdata->server = server;
+
+       if (cifs_sb->ctx->rsize == 0)
+               cifs_sb->ctx->rsize =
+                       server->ops->negotiate_rsize(tlink_tcon(req->cfile->tlink),
+                                                    cifs_sb->ctx);
+
+
+       rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize,
+                                          &rdata->credits);
+       if (rc) {
+               subreq->error = rc;
+               return false;
        }
 
-       rcu_read_unlock();
+       subreq->len = min_t(size_t, subreq->len, rsize);
+#ifdef CONFIG_CIFS_SMB_DIRECT
+       if (server->smbd_conn)
+               subreq->max_nr_segs = server->smbd_conn->max_frmr_depth;
+#endif
+       return true;
 }
 
 /*
- * Failure of write to server.
+ * Issue a read operation on behalf of the netfs helper functions.  We're asked
+ * to make a read of a certain size at a point in the file.  We are permitted
+ * to only read a portion of that, but as long as we read something, the netfs
+ * helper will call us again so that we can issue another read.
  */
-void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len)
+static void cifs_req_issue_read(struct netfs_io_subrequest *subreq)
 {
-       struct address_space *mapping = inode->i_mapping;
-       struct folio *folio;
-       pgoff_t end;
+       struct netfs_io_request *rreq = subreq->rreq;
+       struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq);
+       struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
+       pid_t pid;
+       int rc = 0;
 
-       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
+               pid = req->cfile->pid;
+       else
+               pid = current->tgid; // Ummm...  This may be a workqueue
 
-       if (!len)
-               return;
+       cifs_dbg(FYI, "%s: op=%08x[%x] mapping=%p len=%zu/%zu\n",
+                __func__, rreq->debug_id, subreq->debug_index, rreq->mapping,
+                subreq->transferred, subreq->len);
 
-       rcu_read_lock();
+       if (req->cfile->invalidHandle) {
+               do {
+                       rc = cifs_reopen_file(req->cfile, true);
+               } while (rc == -EAGAIN);
+               if (rc)
+                       goto out;
+       }
 
-       end = (start + len - 1) / PAGE_SIZE;
-       xas_for_each(&xas, folio, end) {
-               if (xas_retry(&xas, folio))
-                       continue;
-               if (!folio_test_writeback(folio)) {
-                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
-                                 len, start, folio->index, end);
-                       continue;
-               }
+       __set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
+       rdata->pid = pid;
 
-               folio_set_error(folio);
-               folio_end_writeback(folio);
+       rc = adjust_credits(rdata->server, &rdata->credits, rdata->subreq.len);
+       if (!rc) {
+               if (rdata->req->cfile->invalidHandle)
+                       rc = -EAGAIN;
+               else
+                       rc = rdata->server->ops->async_readv(rdata);
        }
 
-       rcu_read_unlock();
+out:
+       if (rc)
+               netfs_subreq_terminated(subreq, rc, false);
 }
 
 /*
- * Redirty pages after a temporary failure.
+ * Writeback calls this when it finds a folio that needs uploading.  This isn't
+ * called if writeback only has copy-to-cache to deal with.
  */
-void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len)
+static void cifs_begin_writeback(struct netfs_io_request *wreq)
 {
-       struct address_space *mapping = inode->i_mapping;
-       struct folio *folio;
-       pgoff_t end;
-
-       XA_STATE(xas, &mapping->i_pages, start / PAGE_SIZE);
+       struct cifs_io_request *req = container_of(wreq, struct cifs_io_request, rreq);
+       int ret;
 
-       if (!len)
+       ret = cifs_get_writable_file(CIFS_I(wreq->inode), FIND_WR_ANY, &req->cfile);
+       if (ret) {
+               cifs_dbg(VFS, "No writable handle in writepages ret=%d\n", ret);
                return;
+       }
 
-       rcu_read_lock();
+       wreq->io_streams[0].avail = true;
+}
 
-       end = (start + len - 1) / PAGE_SIZE;
-       xas_for_each(&xas, folio, end) {
-               if (!folio_test_writeback(folio)) {
-                       WARN_ONCE(1, "bad %x @%llx page %lx %lx\n",
-                                 len, start, folio->index, end);
-                       continue;
-               }
+/*
+ * Initialise a request.
+ */
+static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
+{
+       struct cifs_io_request *req = container_of(rreq, struct cifs_io_request, rreq);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
+       struct cifsFileInfo *open_file = NULL;
+
+       rreq->rsize = cifs_sb->ctx->rsize;
+       rreq->wsize = cifs_sb->ctx->wsize;
+
+       if (file) {
+               open_file = file->private_data;
+               rreq->netfs_priv = file->private_data;
+               req->cfile = cifsFileInfo_get(open_file);
+       } else if (rreq->origin != NETFS_WRITEBACK) {
+               WARN_ON_ONCE(1);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/*
+ * Expand the size of a readahead to the size of the rsize, if at least as
+ * large as a page, allowing for the possibility that rsize is not pow-2
+ * aligned.
+ */
+static void cifs_expand_readahead(struct netfs_io_request *rreq)
+{
+       unsigned int rsize = rreq->rsize;
+       loff_t misalignment, i_size = i_size_read(rreq->inode);
+
+       if (rsize < PAGE_SIZE)
+               return;
+
+       if (rsize < INT_MAX)
+               rsize = roundup_pow_of_two(rsize);
+       else
+               rsize = ((unsigned int)INT_MAX + 1) / 2;
 
-               filemap_dirty_folio(folio->mapping, folio);
-               folio_end_writeback(folio);
+       misalignment = rreq->start & (rsize - 1);
+       if (misalignment) {
+               rreq->start -= misalignment;
+               rreq->len += misalignment;
        }
 
-       rcu_read_unlock();
+       rreq->len = round_up(rreq->len, rsize);
+       if (rreq->start < i_size && rreq->len > i_size - rreq->start)
+               rreq->len = i_size - rreq->start;
+}
+
+/*
+ * Completion of a request operation.
+ */
+static void cifs_rreq_done(struct netfs_io_request *rreq)
+{
+       struct timespec64 atime, mtime;
+       struct inode *inode = rreq->inode;
+
+       /* we do not want atime to be less than mtime, it broke some apps */
+       atime = inode_set_atime_to_ts(inode, current_time(inode));
+       mtime = inode_get_mtime(inode);
+       if (timespec64_compare(&atime, &mtime))
+               inode_set_atime_to_ts(inode, inode_get_mtime(inode));
+}
+
+static void cifs_post_modify(struct inode *inode)
+{
+       /* Indication to update ctime and mtime as close is deferred */
+       set_bit(CIFS_INO_MODIFIED_ATTR, &CIFS_I(inode)->flags);
+}
+
+static void cifs_free_request(struct netfs_io_request *rreq)
+{
+       struct cifs_io_request *req = container_of(rreq, struct cifs_io_request, rreq);
+
+       if (req->cfile)
+               cifsFileInfo_put(req->cfile);
 }
 
+static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
+{
+       struct cifs_io_subrequest *rdata =
+               container_of(subreq, struct cifs_io_subrequest, subreq);
+       int rc = subreq->error;
+
+       if (rdata->subreq.source == NETFS_DOWNLOAD_FROM_SERVER) {
+#ifdef CONFIG_CIFS_SMB_DIRECT
+               if (rdata->mr) {
+                       smbd_deregister_mr(rdata->mr);
+                       rdata->mr = NULL;
+               }
+#endif
+       }
+
+       add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+       if (rdata->have_xid)
+               free_xid(rdata->xid);
+}
+
+const struct netfs_request_ops cifs_req_ops = {
+       .request_pool           = &cifs_io_request_pool,
+       .subrequest_pool        = &cifs_io_subrequest_pool,
+       .init_request           = cifs_init_request,
+       .free_request           = cifs_free_request,
+       .free_subrequest        = cifs_free_subrequest,
+       .expand_readahead       = cifs_expand_readahead,
+       .clamp_length           = cifs_clamp_length,
+       .issue_read             = cifs_req_issue_read,
+       .done                   = cifs_rreq_done,
+       .post_modify            = cifs_post_modify,
+       .begin_writeback        = cifs_begin_writeback,
+       .prepare_write          = cifs_prepare_write,
+       .issue_write            = cifs_issue_write,
+};
+
 /*
  * Mark as invalid, all open files on tree connections since they
  * were closed when session to server was lost.
@@ -2207,102 +2397,20 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
        return rc;
 }
 
-/*
- * update the file size (if needed) after a write. Should be called with
- * the inode->i_lock held
- */
-void
-cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
-                     unsigned int bytes_written)
-{
-       loff_t end_of_write = offset + bytes_written;
-
-       if (end_of_write > cifsi->netfs.remote_i_size)
-               netfs_resize_file(&cifsi->netfs, end_of_write, true);
-}
-
-static ssize_t
-cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
-          size_t write_size, loff_t *offset)
+void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
+                                     bool was_async)
 {
-       int rc = 0;
-       unsigned int bytes_written = 0;
-       unsigned int total_written;
-       struct cifs_tcon *tcon;
-       struct TCP_Server_Info *server;
-       unsigned int xid;
-       struct dentry *dentry = open_file->dentry;
-       struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry));
-       struct cifs_io_parms io_parms = {0};
-
-       cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n",
-                write_size, *offset, dentry);
-
-       tcon = tlink_tcon(open_file->tlink);
-       server = tcon->ses->server;
-
-       if (!server->ops->sync_write)
-               return -ENOSYS;
-
-       xid = get_xid();
+       struct netfs_io_request *wreq = wdata->rreq;
+       loff_t new_server_eof;
 
-       for (total_written = 0; write_size > total_written;
-            total_written += bytes_written) {
-               rc = -EAGAIN;
-               while (rc == -EAGAIN) {
-                       struct kvec iov[2];
-                       unsigned int len;
-
-                       if (open_file->invalidHandle) {
-                               /* we could deadlock if we called
-                                  filemap_fdatawait from here so tell
-                                  reopen_file not to flush data to
-                                  server now */
-                               rc = cifs_reopen_file(open_file, false);
-                               if (rc != 0)
-                                       break;
-                       }
+       if (result > 0) {
+               new_server_eof = wdata->subreq.start + wdata->subreq.transferred + result;
 
-                       len = min(server->ops->wp_retry_size(d_inode(dentry)),
-                                 (unsigned int)write_size - total_written);
-                       /* iov[0] is reserved for smb header */
-                       iov[1].iov_base = (char *)write_data + total_written;
-                       iov[1].iov_len = len;
-                       io_parms.pid = pid;
-                       io_parms.tcon = tcon;
-                       io_parms.offset = *offset;
-                       io_parms.length = len;
-                       rc = server->ops->sync_write(xid, &open_file->fid,
-                                       &io_parms, &bytes_written, iov, 1);
-               }
-               if (rc || (bytes_written == 0)) {
-                       if (total_written)
-                               break;
-                       else {
-                               free_xid(xid);
-                               return rc;
-                       }
-               } else {
-                       spin_lock(&d_inode(dentry)->i_lock);
-                       cifs_update_eof(cifsi, *offset, bytes_written);
-                       spin_unlock(&d_inode(dentry)->i_lock);
-                       *offset += bytes_written;
-               }
+               if (new_server_eof > netfs_inode(wreq->inode)->remote_i_size)
+                       netfs_resize_file(netfs_inode(wreq->inode), new_server_eof, true);
        }
 
-       cifs_stats_bytes_written(tcon, total_written);
-
-       if (total_written > 0) {
-               spin_lock(&d_inode(dentry)->i_lock);
-               if (*offset > d_inode(dentry)->i_size) {
-                       i_size_write(d_inode(dentry), *offset);
-                       d_inode(dentry)->i_blocks = (512 - 1 + *offset) >> 9;
-               }
-               spin_unlock(&d_inode(dentry)->i_lock);
-       }
-       mark_inode_dirty_sync(d_inode(dentry));
-       free_xid(xid);
-       return total_written;
+       netfs_write_subrequest_terminated(&wdata->subreq, result, was_async);
 }
 
 struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
@@ -2509,1330 +2617,130 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
        return -ENOENT;
 }
 
-void
-cifs_writedata_release(struct kref *refcount)
-{
-       struct cifs_writedata *wdata = container_of(refcount,
-                                       struct cifs_writedata, refcount);
-#ifdef CONFIG_CIFS_SMB_DIRECT
-       if (wdata->mr) {
-               smbd_deregister_mr(wdata->mr);
-               wdata->mr = NULL;
-       }
-#endif
-
-       if (wdata->cfile)
-               cifsFileInfo_put(wdata->cfile);
-
-       kfree(wdata);
-}
-
 /*
- * Write failed with a retryable error. Resend the write request. It's also
- * possible that the page was redirtied so re-clean the page.
+ * Flush data on a strict file.
  */
-static void
-cifs_writev_requeue(struct cifs_writedata *wdata)
+int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
+                     int datasync)
 {
+       unsigned int xid;
        int rc = 0;
-       struct inode *inode = d_inode(wdata->cfile->dentry);
+       struct cifs_tcon *tcon;
        struct TCP_Server_Info *server;
-       unsigned int rest_len = wdata->bytes;
-       loff_t fpos = wdata->offset;
-
-       server = tlink_tcon(wdata->cfile->tlink)->ses->server;
-       do {
-               struct cifs_writedata *wdata2;
-               unsigned int wsize, cur_len;
-
-               wsize = server->ops->wp_retry_size(inode);
-               if (wsize < rest_len) {
-                       if (wsize < PAGE_SIZE) {
-                               rc = -EOPNOTSUPP;
-                               break;
-                       }
-                       cur_len = min(round_down(wsize, PAGE_SIZE), rest_len);
-               } else {
-                       cur_len = rest_len;
-               }
-
-               wdata2 = cifs_writedata_alloc(cifs_writev_complete);
-               if (!wdata2) {
-                       rc = -ENOMEM;
-                       break;
-               }
-
-               wdata2->sync_mode = wdata->sync_mode;
-               wdata2->offset  = fpos;
-               wdata2->bytes   = cur_len;
-               wdata2->iter    = wdata->iter;
+       struct cifsFileInfo *smbfile = file->private_data;
+       struct inode *inode = file_inode(file);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
-               iov_iter_advance(&wdata2->iter, fpos - wdata->offset);
-               iov_iter_truncate(&wdata2->iter, wdata2->bytes);
+       rc = file_write_and_wait_range(file, start, end);
+       if (rc) {
+               trace_cifs_fsync_err(inode->i_ino, rc);
+               return rc;
+       }
 
-               if (iov_iter_is_xarray(&wdata2->iter))
-                       /* Check for pages having been redirtied and clean
-                        * them.  We can do this by walking the xarray.  If
-                        * it's not an xarray, then it's a DIO and we shouldn't
-                        * be mucking around with the page bits.
-                        */
-                       cifs_undirty_folios(inode, fpos, cur_len);
+       xid = get_xid();
 
-               rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
-                                           &wdata2->cfile);
-               if (!wdata2->cfile) {
-                       cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
-                                rc);
-                       if (!is_retryable_error(rc))
-                               rc = -EBADF;
-               } else {
-                       wdata2->pid = wdata2->cfile->pid;
-                       rc = server->ops->async_writev(wdata2,
-                                                      cifs_writedata_release);
-               }
+       cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n",
+                file, datasync);
 
-               kref_put(&wdata2->refcount, cifs_writedata_release);
+       if (!CIFS_CACHE_READ(CIFS_I(inode))) {
+               rc = cifs_zap_mapping(inode);
                if (rc) {
-                       if (is_retryable_error(rc))
-                               continue;
-                       fpos += cur_len;
-                       rest_len -= cur_len;
-                       break;
+                       cifs_dbg(FYI, "rc: %d during invalidate phase\n", rc);
+                       rc = 0; /* don't care about it in fsync */
                }
-
-               fpos += cur_len;
-               rest_len -= cur_len;
-       } while (rest_len > 0);
-
-       /* Clean up remaining pages from the original wdata */
-       if (iov_iter_is_xarray(&wdata->iter))
-               cifs_pages_write_failed(inode, fpos, rest_len);
-
-       if (rc != 0 && !is_retryable_error(rc))
-               mapping_set_error(inode->i_mapping, rc);
-       kref_put(&wdata->refcount, cifs_writedata_release);
-}
-
-void
-cifs_writev_complete(struct work_struct *work)
-{
-       struct cifs_writedata *wdata = container_of(work,
-                                               struct cifs_writedata, work);
-       struct inode *inode = d_inode(wdata->cfile->dentry);
-
-       if (wdata->result == 0) {
-               spin_lock(&inode->i_lock);
-               cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
-               spin_unlock(&inode->i_lock);
-               cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
-                                        wdata->bytes);
-       } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
-               return cifs_writev_requeue(wdata);
-
-       if (wdata->result == -EAGAIN)
-               cifs_pages_write_redirty(inode, wdata->offset, wdata->bytes);
-       else if (wdata->result < 0)
-               cifs_pages_write_failed(inode, wdata->offset, wdata->bytes);
-       else
-               cifs_pages_written_back(inode, wdata->offset, wdata->bytes);
-
-       if (wdata->result != -EAGAIN)
-               mapping_set_error(inode->i_mapping, wdata->result);
-       kref_put(&wdata->refcount, cifs_writedata_release);
-}
-
-struct cifs_writedata *cifs_writedata_alloc(work_func_t complete)
-{
-       struct cifs_writedata *wdata;
-
-       wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
-       if (wdata != NULL) {
-               kref_init(&wdata->refcount);
-               INIT_LIST_HEAD(&wdata->list);
-               init_completion(&wdata->done);
-               INIT_WORK(&wdata->work, complete);
-       }
-       return wdata;
-}
-
-static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
-{
-       struct address_space *mapping = page->mapping;
-       loff_t offset = (loff_t)page->index << PAGE_SHIFT;
-       char *write_data;
-       int rc = -EFAULT;
-       int bytes_written = 0;
-       struct inode *inode;
-       struct cifsFileInfo *open_file;
-
-       if (!mapping || !mapping->host)
-               return -EFAULT;
-
-       inode = page->mapping->host;
-
-       offset += (loff_t)from;
-       write_data = kmap(page);
-       write_data += from;
-
-       if ((to > PAGE_SIZE) || (from > to)) {
-               kunmap(page);
-               return -EIO;
-       }
-
-       /* racing with truncate? */
-       if (offset > mapping->host->i_size) {
-               kunmap(page);
-               return 0; /* don't care */
        }
 
-       /* check to make sure that we are not extending the file */
-       if (mapping->host->i_size - offset < (loff_t)to)
-               to = (unsigned)(mapping->host->i_size - offset);
+       tcon = tlink_tcon(smbfile->tlink);
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
+               server = tcon->ses->server;
+               if (server->ops->flush == NULL) {
+                       rc = -ENOSYS;
+                       goto strict_fsync_exit;
+               }
 
-       rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY,
-                                   &open_file);
-       if (!rc) {
-               bytes_written = cifs_write(open_file, open_file->pid,
-                                          write_data, to - from, &offset);
-               cifsFileInfo_put(open_file);
-               /* Does mm or vfs already set times? */
-               simple_inode_init_ts(inode);
-               if ((bytes_written > 0) && (offset))
-                       rc = 0;
-               else if (bytes_written < 0)
-                       rc = bytes_written;
-               else
-                       rc = -EFAULT;
-       } else {
-               cifs_dbg(FYI, "No writable handle for write page rc=%d\n", rc);
-               if (!is_retryable_error(rc))
-                       rc = -EIO;
+               if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
+                       smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
+                       if (smbfile) {
+                               rc = server->ops->flush(xid, tcon, &smbfile->fid);
+                               cifsFileInfo_put(smbfile);
+                       } else
+                               cifs_dbg(FYI, "ignore fsync for file not open for write\n");
+               } else
+                       rc = server->ops->flush(xid, tcon, &smbfile->fid);
        }
 
-       kunmap(page);
+strict_fsync_exit:
+       free_xid(xid);
        return rc;
 }
 
 /*
- * Extend the region to be written back to include subsequent contiguously
- * dirty pages if possible, but don't sleep while doing so.
+ * Flush data on a non-strict data.
  */
-static void cifs_extend_writeback(struct address_space *mapping,
-                                 struct xa_state *xas,
-                                 long *_count,
-                                 loff_t start,
-                                 int max_pages,
-                                 loff_t max_len,
-                                 size_t *_len)
+int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
-       struct folio_batch batch;
-       struct folio *folio;
-       unsigned int nr_pages;
-       pgoff_t index = (start + *_len) / PAGE_SIZE;
-       size_t len;
-       bool stop = true;
-       unsigned int i;
+       unsigned int xid;
+       int rc = 0;
+       struct cifs_tcon *tcon;
+       struct TCP_Server_Info *server;
+       struct cifsFileInfo *smbfile = file->private_data;
+       struct inode *inode = file_inode(file);
+       struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
 
-       folio_batch_init(&batch);
+       rc = file_write_and_wait_range(file, start, end);
+       if (rc) {
+               trace_cifs_fsync_err(file_inode(file)->i_ino, rc);
+               return rc;
+       }
 
-       do {
-               /* Firstly, we gather up a batch of contiguous dirty pages
-                * under the RCU read lock - but we can't clear the dirty flags
-                * there if any of those pages are mapped.
-                */
-               rcu_read_lock();
+       xid = get_xid();
 
-               xas_for_each(xas, folio, ULONG_MAX) {
-                       stop = true;
-                       if (xas_retry(xas, folio))
-                               continue;
-                       if (xa_is_value(folio))
-                               break;
-                       if (folio->index != index) {
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       if (!folio_try_get_rcu(folio)) {
-                               xas_reset(xas);
-                               continue;
-                       }
-                       nr_pages = folio_nr_pages(folio);
-                       if (nr_pages > max_pages) {
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       /* Has the page moved or been split? */
-                       if (unlikely(folio != xas_reload(xas))) {
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       if (!folio_trylock(folio)) {
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-                       if (!folio_test_dirty(folio) ||
-                           folio_test_writeback(folio)) {
-                               folio_unlock(folio);
-                               folio_put(folio);
-                               xas_reset(xas);
-                               break;
-                       }
-
-                       max_pages -= nr_pages;
-                       len = folio_size(folio);
-                       stop = false;
-
-                       index += nr_pages;
-                       *_count -= nr_pages;
-                       *_len += len;
-                       if (max_pages <= 0 || *_len >= max_len || *_count <= 0)
-                               stop = true;
-
-                       if (!folio_batch_add(&batch, folio))
-                               break;
-                       if (stop)
-                               break;
-               }
-
-               xas_pause(xas);
-               rcu_read_unlock();
-
-               /* Now, if we obtained any pages, we can shift them to being
-                * writable and mark them for caching.
-                */
-               if (!folio_batch_count(&batch))
-                       break;
-
-               for (i = 0; i < folio_batch_count(&batch); i++) {
-                       folio = batch.folios[i];
-                       /* The folio should be locked, dirty and not undergoing
-                        * writeback from the loop above.
-                        */
-                       if (!folio_clear_dirty_for_io(folio))
-                               WARN_ON(1);
-                       folio_start_writeback(folio);
-                       folio_unlock(folio);
-               }
-
-               folio_batch_release(&batch);
-               cond_resched();
-       } while (!stop);
-}
-
-/*
- * Write back the locked page and any subsequent non-locked dirty pages.
- */
-static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
-                                                struct writeback_control *wbc,
-                                                struct xa_state *xas,
-                                                struct folio *folio,
-                                                unsigned long long start,
-                                                unsigned long long end)
-{
-       struct inode *inode = mapping->host;
-       struct TCP_Server_Info *server;
-       struct cifs_writedata *wdata;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-       struct cifs_credits credits_on_stack;
-       struct cifs_credits *credits = &credits_on_stack;
-       struct cifsFileInfo *cfile = NULL;
-       unsigned long long i_size = i_size_read(inode), max_len;
-       unsigned int xid, wsize;
-       size_t len = folio_size(folio);
-       long count = wbc->nr_to_write;
-       int rc;
-
-       /* The folio should be locked, dirty and not undergoing writeback. */
-       if (!folio_clear_dirty_for_io(folio))
-               WARN_ON_ONCE(1);
-       folio_start_writeback(folio);
-
-       count -= folio_nr_pages(folio);
-
-       xid = get_xid();
-       server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses);
-
-       rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile);
-       if (rc) {
-               cifs_dbg(VFS, "No writable handle in writepages rc=%d\n", rc);
-               goto err_xid;
-       }
-
-       rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
-                                          &wsize, credits);
-       if (rc != 0)
-               goto err_close;
-
-       wdata = cifs_writedata_alloc(cifs_writev_complete);
-       if (!wdata) {
-               rc = -ENOMEM;
-               goto err_uncredit;
-       }
-
-       wdata->sync_mode = wbc->sync_mode;
-       wdata->offset = folio_pos(folio);
-       wdata->pid = cfile->pid;
-       wdata->credits = credits_on_stack;
-       wdata->cfile = cfile;
-       wdata->server = server;
-       cfile = NULL;
-
-       /* Find all consecutive lockable dirty pages that have contiguous
-        * written regions, stopping when we find a page that is not
-        * immediately lockable, is not dirty or is missing, or we reach the
-        * end of the range.
-        */
-       if (start < i_size) {
-               /* Trim the write to the EOF; the extra data is ignored.  Also
-                * put an upper limit on the size of a single storedata op.
-                */
-               max_len = wsize;
-               max_len = min_t(unsigned long long, max_len, end - start + 1);
-               max_len = min_t(unsigned long long, max_len, i_size - start);
-
-               if (len < max_len) {
-                       int max_pages = INT_MAX;
-
-#ifdef CONFIG_CIFS_SMB_DIRECT
-                       if (server->smbd_conn)
-                               max_pages = server->smbd_conn->max_frmr_depth;
-#endif
-                       max_pages -= folio_nr_pages(folio);
-
-                       if (max_pages > 0)
-                               cifs_extend_writeback(mapping, xas, &count, start,
-                                                     max_pages, max_len, &len);
-               }
-       }
-       len = min_t(unsigned long long, len, i_size - start);
-
-       /* We now have a contiguous set of dirty pages, each with writeback
-        * set; the first page is still locked at this point, but all the rest
-        * have been unlocked.
-        */
-       folio_unlock(folio);
-       wdata->bytes = len;
-
-       if (start < i_size) {
-               iov_iter_xarray(&wdata->iter, ITER_SOURCE, &mapping->i_pages,
-                               start, len);
-
-               rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes);
-               if (rc)
-                       goto err_wdata;
-
-               if (wdata->cfile->invalidHandle)
-                       rc = -EAGAIN;
-               else
-                       rc = wdata->server->ops->async_writev(wdata,
-                                                             cifs_writedata_release);
-               if (rc >= 0) {
-                       kref_put(&wdata->refcount, cifs_writedata_release);
-                       goto err_close;
-               }
-       } else {
-               /* The dirty region was entirely beyond the EOF. */
-               cifs_pages_written_back(inode, start, len);
-               rc = 0;
-       }
-
-err_wdata:
-       kref_put(&wdata->refcount, cifs_writedata_release);
-err_uncredit:
-       add_credits_and_wake_if(server, credits, 0);
-err_close:
-       if (cfile)
-               cifsFileInfo_put(cfile);
-err_xid:
-       free_xid(xid);
-       if (rc == 0) {
-               wbc->nr_to_write = count;
-               rc = len;
-       } else if (is_retryable_error(rc)) {
-               cifs_pages_write_redirty(inode, start, len);
-       } else {
-               cifs_pages_write_failed(inode, start, len);
-               mapping_set_error(mapping, rc);
-       }
-       /* Indication to update ctime and mtime as close is deferred */
-       set_bit(CIFS_INO_MODIFIED_ATTR, &CIFS_I(inode)->flags);
-       return rc;
-}
-
-/*
- * write a region of pages back to the server
- */
-static ssize_t cifs_writepages_begin(struct address_space *mapping,
-                                    struct writeback_control *wbc,
-                                    struct xa_state *xas,
-                                    unsigned long long *_start,
-                                    unsigned long long end)
-{
-       struct folio *folio;
-       unsigned long long start = *_start;
-       ssize_t ret;
-       int skips = 0;
-
-search_again:
-       /* Find the first dirty page. */
-       rcu_read_lock();
-
-       for (;;) {
-               folio = xas_find_marked(xas, end / PAGE_SIZE, PAGECACHE_TAG_DIRTY);
-               if (xas_retry(xas, folio) || xa_is_value(folio))
-                       continue;
-               if (!folio)
-                       break;
-
-               if (!folio_try_get_rcu(folio)) {
-                       xas_reset(xas);
-                       continue;
-               }
-
-               if (unlikely(folio != xas_reload(xas))) {
-                       folio_put(folio);
-                       xas_reset(xas);
-                       continue;
-               }
-
-               xas_pause(xas);
-               break;
-       }
-       rcu_read_unlock();
-       if (!folio)
-               return 0;
-
-       start = folio_pos(folio); /* May regress with THPs */
-
-       /* At this point we hold neither the i_pages lock nor the page lock:
-        * the page may be truncated or invalidated (changing page->mapping to
-        * NULL), or even swizzled back from swapper_space to tmpfs file
-        * mapping
-        */
-lock_again:
-       if (wbc->sync_mode != WB_SYNC_NONE) {
-               ret = folio_lock_killable(folio);
-               if (ret < 0)
-                       return ret;
-       } else {
-               if (!folio_trylock(folio))
-                       goto search_again;
-       }
-
-       if (folio->mapping != mapping ||
-           !folio_test_dirty(folio)) {
-               start += folio_size(folio);
-               folio_unlock(folio);
-               goto search_again;
-       }
-
-       if (folio_test_writeback(folio) ||
-           folio_test_fscache(folio)) {
-               folio_unlock(folio);
-               if (wbc->sync_mode != WB_SYNC_NONE) {
-                       folio_wait_writeback(folio);
-#ifdef CONFIG_CIFS_FSCACHE
-                       folio_wait_fscache(folio);
-#endif
-                       goto lock_again;
-               }
-
-               start += folio_size(folio);
-               if (wbc->sync_mode == WB_SYNC_NONE) {
-                       if (skips >= 5 || need_resched()) {
-                               ret = 0;
-                               goto out;
-                       }
-                       skips++;
-               }
-               goto search_again;
-       }
-
-       ret = cifs_write_back_from_locked_folio(mapping, wbc, xas, folio, start, end);
-out:
-       if (ret > 0)
-               *_start = start + ret;
-       return ret;
-}
-
-/*
- * Write a region of pages back to the server
- */
-static int cifs_writepages_region(struct address_space *mapping,
-                                 struct writeback_control *wbc,
-                                 unsigned long long *_start,
-                                 unsigned long long end)
-{
-       ssize_t ret;
-
-       XA_STATE(xas, &mapping->i_pages, *_start / PAGE_SIZE);
-
-       do {
-               ret = cifs_writepages_begin(mapping, wbc, &xas, _start, end);
-               if (ret > 0 && wbc->nr_to_write > 0)
-                       cond_resched();
-       } while (ret > 0 && wbc->nr_to_write > 0);
-
-       return ret > 0 ? 0 : ret;
-}
-
-/*
- * Write some of the pending data back to the server
- */
-static int cifs_writepages(struct address_space *mapping,
-                          struct writeback_control *wbc)
-{
-       loff_t start, end;
-       int ret;
-
-       /* We have to be careful as we can end up racing with setattr()
-        * truncating the pagecache since the caller doesn't take a lock here
-        * to prevent it.
-        */
-
-       if (wbc->range_cyclic && mapping->writeback_index) {
-               start = mapping->writeback_index * PAGE_SIZE;
-               ret = cifs_writepages_region(mapping, wbc, &start, LLONG_MAX);
-               if (ret < 0)
-                       goto out;
-
-               if (wbc->nr_to_write <= 0) {
-                       mapping->writeback_index = start / PAGE_SIZE;
-                       goto out;
-               }
-
-               start = 0;
-               end = mapping->writeback_index * PAGE_SIZE;
-               mapping->writeback_index = 0;
-               ret = cifs_writepages_region(mapping, wbc, &start, end);
-               if (ret == 0)
-                       mapping->writeback_index = start / PAGE_SIZE;
-       } else if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) {
-               start = 0;
-               ret = cifs_writepages_region(mapping, wbc, &start, LLONG_MAX);
-               if (wbc->nr_to_write > 0 && ret == 0)
-                       mapping->writeback_index = start / PAGE_SIZE;
-       } else {
-               start = wbc->range_start;
-               ret = cifs_writepages_region(mapping, wbc, &start, wbc->range_end);
-       }
-
-out:
-       return ret;
-}
-
-static int
-cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
-{
-       int rc;
-       unsigned int xid;
-
-       xid = get_xid();
-/* BB add check for wbc flags */
-       get_page(page);
-       if (!PageUptodate(page))
-               cifs_dbg(FYI, "ppw - page not up to date\n");
-
-       /*
-        * Set the "writeback" flag, and clear "dirty" in the radix tree.
-        *
-        * A writepage() implementation always needs to do either this,
-        * or re-dirty the page with "redirty_page_for_writepage()" in
-        * the case of a failure.
-        *
-        * Just unlocking the page will cause the radix tree tag-bits
-        * to fail to update with the state of the page correctly.
-        */
-       set_page_writeback(page);
-retry_write:
-       rc = cifs_partialpagewrite(page, 0, PAGE_SIZE);
-       if (is_retryable_error(rc)) {
-               if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN)
-                       goto retry_write;
-               redirty_page_for_writepage(wbc, page);
-       } else if (rc != 0) {
-               SetPageError(page);
-               mapping_set_error(page->mapping, rc);
-       } else {
-               SetPageUptodate(page);
-       }
-       end_page_writeback(page);
-       put_page(page);
-       free_xid(xid);
-       return rc;
-}
-
-static int cifs_write_end(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len, unsigned copied,
-                       struct page *page, void *fsdata)
-{
-       int rc;
-       struct inode *inode = mapping->host;
-       struct cifsFileInfo *cfile = file->private_data;
-       struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
-       struct folio *folio = page_folio(page);
-       __u32 pid;
-
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
-               pid = cfile->pid;
-       else
-               pid = current->tgid;
-
-       cifs_dbg(FYI, "write_end for page %p from pos %lld with %d bytes\n",
-                page, pos, copied);
-
-       if (folio_test_checked(folio)) {
-               if (copied == len)
-                       folio_mark_uptodate(folio);
-               folio_clear_checked(folio);
-       } else if (!folio_test_uptodate(folio) && copied == PAGE_SIZE)
-               folio_mark_uptodate(folio);
-
-       if (!folio_test_uptodate(folio)) {
-               char *page_data;
-               unsigned offset = pos & (PAGE_SIZE - 1);
-               unsigned int xid;
-
-               xid = get_xid();
-               /* this is probably better than directly calling
-                  partialpage_write since in this function the file handle is
-                  known which we might as well leverage */
-               /* BB check if anything else missing out of ppw
-                  such as updating last write time */
-               page_data = kmap(page);
-               rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
-               /* if (rc < 0) should we set writebehind rc? */
-               kunmap(page);
-
-               free_xid(xid);
-       } else {
-               rc = copied;
-               pos += copied;
-               set_page_dirty(page);
-       }
-
-       if (rc > 0) {
-               spin_lock(&inode->i_lock);
-               if (pos > inode->i_size) {
-                       loff_t additional_blocks = (512 - 1 + copied) >> 9;
-
-                       i_size_write(inode, pos);
-                       /*
-                        * Estimate new allocation size based on the amount written.
-                        * This will be updated from server on close (and on queryinfo)
-                        */
-                       inode->i_blocks = min_t(blkcnt_t, (512 - 1 + pos) >> 9,
-                                               inode->i_blocks + additional_blocks);
-               }
-               spin_unlock(&inode->i_lock);
-       }
-
-       unlock_page(page);
-       put_page(page);
-       /* Indication to update ctime and mtime as close is deferred */
-       set_bit(CIFS_INO_MODIFIED_ATTR, &CIFS_I(inode)->flags);
-
-       return rc;
-}
-
-int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
-                     int datasync)
-{
-       unsigned int xid;
-       int rc = 0;
-       struct cifs_tcon *tcon;
-       struct TCP_Server_Info *server;
-       struct cifsFileInfo *smbfile = file->private_data;
-       struct inode *inode = file_inode(file);
-       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
-       rc = file_write_and_wait_range(file, start, end);
-       if (rc) {
-               trace_cifs_fsync_err(inode->i_ino, rc);
-               return rc;
-       }
-
-       xid = get_xid();
-
-       cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n",
-                file, datasync);
-
-       if (!CIFS_CACHE_READ(CIFS_I(inode))) {
-               rc = cifs_zap_mapping(inode);
-               if (rc) {
-                       cifs_dbg(FYI, "rc: %d during invalidate phase\n", rc);
-                       rc = 0; /* don't care about it in fsync */
-               }
-       }
-
-       tcon = tlink_tcon(smbfile->tlink);
-       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
-               server = tcon->ses->server;
-               if (server->ops->flush == NULL) {
-                       rc = -ENOSYS;
-                       goto strict_fsync_exit;
-               }
-
-               if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
-                       smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
-                       if (smbfile) {
-                               rc = server->ops->flush(xid, tcon, &smbfile->fid);
-                               cifsFileInfo_put(smbfile);
-                       } else
-                               cifs_dbg(FYI, "ignore fsync for file not open for write\n");
-               } else
-                       rc = server->ops->flush(xid, tcon, &smbfile->fid);
-       }
-
-strict_fsync_exit:
-       free_xid(xid);
-       return rc;
-}
-
-int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
-       unsigned int xid;
-       int rc = 0;
-       struct cifs_tcon *tcon;
-       struct TCP_Server_Info *server;
-       struct cifsFileInfo *smbfile = file->private_data;
-       struct inode *inode = file_inode(file);
-       struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
-
-       rc = file_write_and_wait_range(file, start, end);
-       if (rc) {
-               trace_cifs_fsync_err(file_inode(file)->i_ino, rc);
-               return rc;
-       }
-
-       xid = get_xid();
-
-       cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n",
-                file, datasync);
-
-       tcon = tlink_tcon(smbfile->tlink);
-       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
-               server = tcon->ses->server;
-               if (server->ops->flush == NULL) {
-                       rc = -ENOSYS;
-                       goto fsync_exit;
-               }
-
-               if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
-                       smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
-                       if (smbfile) {
-                               rc = server->ops->flush(xid, tcon, &smbfile->fid);
-                               cifsFileInfo_put(smbfile);
-                       } else
-                               cifs_dbg(FYI, "ignore fsync for file not open for write\n");
-               } else
-                       rc = server->ops->flush(xid, tcon, &smbfile->fid);
-       }
-
-fsync_exit:
-       free_xid(xid);
-       return rc;
-}
-
-/*
- * As file closes, flush all cached write data for this inode checking
- * for write behind errors.
- */
-int cifs_flush(struct file *file, fl_owner_t id)
-{
-       struct inode *inode = file_inode(file);
-       int rc = 0;
-
-       if (file->f_mode & FMODE_WRITE)
-               rc = filemap_write_and_wait(inode->i_mapping);
-
-       cifs_dbg(FYI, "Flush inode %p file %p rc %d\n", inode, file, rc);
-       if (rc) {
-               /* get more nuanced writeback errors */
-               rc = filemap_check_wb_err(file->f_mapping, 0);
-               trace_cifs_flush_err(inode->i_ino, rc);
-       }
-       return rc;
-}
-
-static void
-cifs_uncached_writedata_release(struct kref *refcount)
-{
-       struct cifs_writedata *wdata = container_of(refcount,
-                                       struct cifs_writedata, refcount);
-
-       kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release);
-       cifs_writedata_release(refcount);
-}
-
-static void collect_uncached_write_data(struct cifs_aio_ctx *ctx);
-
-static void
-cifs_uncached_writev_complete(struct work_struct *work)
-{
-       struct cifs_writedata *wdata = container_of(work,
-                                       struct cifs_writedata, work);
-       struct inode *inode = d_inode(wdata->cfile->dentry);
-       struct cifsInodeInfo *cifsi = CIFS_I(inode);
-
-       spin_lock(&inode->i_lock);
-       cifs_update_eof(cifsi, wdata->offset, wdata->bytes);
-       if (cifsi->netfs.remote_i_size > inode->i_size)
-               i_size_write(inode, cifsi->netfs.remote_i_size);
-       spin_unlock(&inode->i_lock);
-
-       complete(&wdata->done);
-       collect_uncached_write_data(wdata->ctx);
-       /* the below call can possibly free the last ref to aio ctx */
-       kref_put(&wdata->refcount, cifs_uncached_writedata_release);
-}
-
-static int
-cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
-       struct cifs_aio_ctx *ctx)
-{
-       unsigned int wsize;
-       struct cifs_credits credits;
-       int rc;
-       struct TCP_Server_Info *server = wdata->server;
-
-       do {
-               if (wdata->cfile->invalidHandle) {
-                       rc = cifs_reopen_file(wdata->cfile, false);
-                       if (rc == -EAGAIN)
-                               continue;
-                       else if (rc)
-                               break;
-               }
-
-
-               /*
-                * Wait for credits to resend this wdata.
-                * Note: we are attempting to resend the whole wdata not in
-                * segments
-                */
-               do {
-                       rc = server->ops->wait_mtu_credits(server, wdata->bytes,
-                                               &wsize, &credits);
-                       if (rc)
-                               goto fail;
-
-                       if (wsize < wdata->bytes) {
-                               add_credits_and_wake_if(server, &credits, 0);
-                               msleep(1000);
-                       }
-               } while (wsize < wdata->bytes);
-               wdata->credits = credits;
-
-               rc = adjust_credits(server, &wdata->credits, wdata->bytes);
-
-               if (!rc) {
-                       if (wdata->cfile->invalidHandle)
-                               rc = -EAGAIN;
-                       else {
-                               wdata->replay = true;
-#ifdef CONFIG_CIFS_SMB_DIRECT
-                               if (wdata->mr) {
-                                       wdata->mr->need_invalidate = true;
-                                       smbd_deregister_mr(wdata->mr);
-                                       wdata->mr = NULL;
-                               }
-#endif
-                               rc = server->ops->async_writev(wdata,
-                                       cifs_uncached_writedata_release);
-                       }
-               }
-
-               /* If the write was successfully sent, we are done */
-               if (!rc) {
-                       list_add_tail(&wdata->list, wdata_list);
-                       return 0;
-               }
-
-               /* Roll back credits and retry if needed */
-               add_credits_and_wake_if(server, &wdata->credits, 0);
-       } while (rc == -EAGAIN);
-
-fail:
-       kref_put(&wdata->refcount, cifs_uncached_writedata_release);
-       return rc;
-}
-
-/*
- * Select span of a bvec iterator we're going to use.  Limit it by both maximum
- * size and maximum number of segments.
- */
-static size_t cifs_limit_bvec_subset(const struct iov_iter *iter, size_t max_size,
-                                    size_t max_segs, unsigned int *_nsegs)
-{
-       const struct bio_vec *bvecs = iter->bvec;
-       unsigned int nbv = iter->nr_segs, ix = 0, nsegs = 0;
-       size_t len, span = 0, n = iter->count;
-       size_t skip = iter->iov_offset;
-
-       if (WARN_ON(!iov_iter_is_bvec(iter)) || n == 0)
-               return 0;
-
-       while (n && ix < nbv && skip) {
-               len = bvecs[ix].bv_len;
-               if (skip < len)
-                       break;
-               skip -= len;
-               n -= len;
-               ix++;
-       }
-
-       while (n && ix < nbv) {
-               len = min3(n, bvecs[ix].bv_len - skip, max_size);
-               span += len;
-               max_size -= len;
-               nsegs++;
-               ix++;
-               if (max_size == 0 || nsegs >= max_segs)
-                       break;
-               skip = 0;
-               n -= len;
-       }
-
-       *_nsegs = nsegs;
-       return span;
-}
-
-static int
-cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
-                    struct cifsFileInfo *open_file,
-                    struct cifs_sb_info *cifs_sb, struct list_head *wdata_list,
-                    struct cifs_aio_ctx *ctx)
-{
-       int rc = 0;
-       size_t cur_len, max_len;
-       struct cifs_writedata *wdata;
-       pid_t pid;
-       struct TCP_Server_Info *server;
-       unsigned int xid, max_segs = INT_MAX;
-
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
-               pid = open_file->pid;
-       else
-               pid = current->tgid;
-
-       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
-       xid = get_xid();
-
-#ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->smbd_conn)
-               max_segs = server->smbd_conn->max_frmr_depth;
-#endif
-
-       do {
-               struct cifs_credits credits_on_stack;
-               struct cifs_credits *credits = &credits_on_stack;
-               unsigned int wsize, nsegs = 0;
-
-               if (signal_pending(current)) {
-                       rc = -EINTR;
-                       break;
-               }
-
-               if (open_file->invalidHandle) {
-                       rc = cifs_reopen_file(open_file, false);
-                       if (rc == -EAGAIN)
-                               continue;
-                       else if (rc)
-                               break;
-               }
-
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
-                                                  &wsize, credits);
-               if (rc)
-                       break;
-
-               max_len = min_t(const size_t, len, wsize);
-               if (!max_len) {
-                       rc = -EAGAIN;
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               cur_len = cifs_limit_bvec_subset(from, max_len, max_segs, &nsegs);
-               cifs_dbg(FYI, "write_from_iter len=%zx/%zx nsegs=%u/%lu/%u\n",
-                        cur_len, max_len, nsegs, from->nr_segs, max_segs);
-               if (cur_len == 0) {
-                       rc = -EIO;
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               wdata = cifs_writedata_alloc(cifs_uncached_writev_complete);
-               if (!wdata) {
-                       rc = -ENOMEM;
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               wdata->sync_mode = WB_SYNC_ALL;
-               wdata->offset   = (__u64)fpos;
-               wdata->cfile    = cifsFileInfo_get(open_file);
-               wdata->server   = server;
-               wdata->pid      = pid;
-               wdata->bytes    = cur_len;
-               wdata->credits  = credits_on_stack;
-               wdata->iter     = *from;
-               wdata->ctx      = ctx;
-               kref_get(&ctx->refcount);
-
-               iov_iter_truncate(&wdata->iter, cur_len);
-
-               rc = adjust_credits(server, &wdata->credits, wdata->bytes);
-
-               if (!rc) {
-                       if (wdata->cfile->invalidHandle)
-                               rc = -EAGAIN;
-                       else
-                               rc = server->ops->async_writev(wdata,
-                                       cifs_uncached_writedata_release);
-               }
-
-               if (rc) {
-                       add_credits_and_wake_if(server, &wdata->credits, 0);
-                       kref_put(&wdata->refcount,
-                                cifs_uncached_writedata_release);
-                       if (rc == -EAGAIN)
-                               continue;
-                       break;
-               }
-
-               list_add_tail(&wdata->list, wdata_list);
-               iov_iter_advance(from, cur_len);
-               fpos += cur_len;
-               len -= cur_len;
-       } while (len > 0);
-
-       free_xid(xid);
-       return rc;
-}
-
-static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
-{
-       struct cifs_writedata *wdata, *tmp;
-       struct cifs_tcon *tcon;
-       struct cifs_sb_info *cifs_sb;
-       struct dentry *dentry = ctx->cfile->dentry;
-       ssize_t rc;
-
-       tcon = tlink_tcon(ctx->cfile->tlink);
-       cifs_sb = CIFS_SB(dentry->d_sb);
-
-       mutex_lock(&ctx->aio_mutex);
-
-       if (list_empty(&ctx->list)) {
-               mutex_unlock(&ctx->aio_mutex);
-               return;
-       }
-
-       rc = ctx->rc;
-       /*
-        * Wait for and collect replies for any successful sends in order of
-        * increasing offset. Once an error is hit, then return without waiting
-        * for any more replies.
-        */
-restart_loop:
-       list_for_each_entry_safe(wdata, tmp, &ctx->list, list) {
-               if (!rc) {
-                       if (!try_wait_for_completion(&wdata->done)) {
-                               mutex_unlock(&ctx->aio_mutex);
-                               return;
-                       }
-
-                       if (wdata->result)
-                               rc = wdata->result;
-                       else
-                               ctx->total_len += wdata->bytes;
-
-                       /* resend call if it's a retryable error */
-                       if (rc == -EAGAIN) {
-                               struct list_head tmp_list;
-                               struct iov_iter tmp_from = ctx->iter;
-
-                               INIT_LIST_HEAD(&tmp_list);
-                               list_del_init(&wdata->list);
-
-                               if (ctx->direct_io)
-                                       rc = cifs_resend_wdata(
-                                               wdata, &tmp_list, ctx);
-                               else {
-                                       iov_iter_advance(&tmp_from,
-                                                wdata->offset - ctx->pos);
-
-                                       rc = cifs_write_from_iter(wdata->offset,
-                                               wdata->bytes, &tmp_from,
-                                               ctx->cfile, cifs_sb, &tmp_list,
-                                               ctx);
-
-                                       kref_put(&wdata->refcount,
-                                               cifs_uncached_writedata_release);
-                               }
-
-                               list_splice(&tmp_list, &ctx->list);
-                               goto restart_loop;
-                       }
-               }
-               list_del_init(&wdata->list);
-               kref_put(&wdata->refcount, cifs_uncached_writedata_release);
-       }
-
-       cifs_stats_bytes_written(tcon, ctx->total_len);
-       set_bit(CIFS_INO_INVALID_MAPPING, &CIFS_I(dentry->d_inode)->flags);
-
-       ctx->rc = (rc == 0) ? ctx->total_len : rc;
-
-       mutex_unlock(&ctx->aio_mutex);
-
-       if (ctx->iocb && ctx->iocb->ki_complete)
-               ctx->iocb->ki_complete(ctx->iocb, ctx->rc);
-       else
-               complete(&ctx->done);
-}
-
-static ssize_t __cifs_writev(
-       struct kiocb *iocb, struct iov_iter *from, bool direct)
-{
-       struct file *file = iocb->ki_filp;
-       ssize_t total_written = 0;
-       struct cifsFileInfo *cfile;
-       struct cifs_tcon *tcon;
-       struct cifs_sb_info *cifs_sb;
-       struct cifs_aio_ctx *ctx;
-       int rc;
-
-       rc = generic_write_checks(iocb, from);
-       if (rc <= 0)
-               return rc;
-
-       cifs_sb = CIFS_FILE_SB(file);
-       cfile = file->private_data;
-       tcon = tlink_tcon(cfile->tlink);
-
-       if (!tcon->ses->server->ops->async_writev)
-               return -ENOSYS;
-
-       ctx = cifs_aio_ctx_alloc();
-       if (!ctx)
-               return -ENOMEM;
-
-       ctx->cfile = cifsFileInfo_get(cfile);
-
-       if (!is_sync_kiocb(iocb))
-               ctx->iocb = iocb;
-
-       ctx->pos = iocb->ki_pos;
-       ctx->direct_io = direct;
-       ctx->nr_pinned_pages = 0;
-
-       if (user_backed_iter(from)) {
-               /*
-                * Extract IOVEC/UBUF-type iterators to a BVEC-type iterator as
-                * they contain references to the calling process's virtual
-                * memory layout which won't be available in an async worker
-                * thread.  This also takes a pin on every folio involved.
-                */
-               rc = netfs_extract_user_iter(from, iov_iter_count(from),
-                                            &ctx->iter, 0);
-               if (rc < 0) {
-                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-                       return rc;
-               }
+       cifs_dbg(FYI, "Sync file - name: %pD datasync: 0x%x\n",
+                file, datasync);
 
-               ctx->nr_pinned_pages = rc;
-               ctx->bv = (void *)ctx->iter.bvec;
-               ctx->bv_need_unpin = iov_iter_extract_will_pin(from);
-       } else if ((iov_iter_is_bvec(from) || iov_iter_is_kvec(from)) &&
-                  !is_sync_kiocb(iocb)) {
-               /*
-                * If the op is asynchronous, we need to copy the list attached
-                * to a BVEC/KVEC-type iterator, but we assume that the storage
-                * will be pinned by the caller; in any case, we may or may not
-                * be able to pin the pages, so we don't try.
-                */
-               ctx->bv = (void *)dup_iter(&ctx->iter, from, GFP_KERNEL);
-               if (!ctx->bv) {
-                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-                       return -ENOMEM;
+       tcon = tlink_tcon(smbfile->tlink);
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
+               server = tcon->ses->server;
+               if (server->ops->flush == NULL) {
+                       rc = -ENOSYS;
+                       goto fsync_exit;
                }
-       } else {
-               /*
-                * Otherwise, we just pass the iterator down as-is and rely on
-                * the caller to make sure the pages referred to by the
-                * iterator don't evaporate.
-                */
-               ctx->iter = *from;
-       }
-
-       ctx->len = iov_iter_count(&ctx->iter);
 
-       /* grab a lock here due to read response handlers can access ctx */
-       mutex_lock(&ctx->aio_mutex);
-
-       rc = cifs_write_from_iter(iocb->ki_pos, ctx->len, &ctx->iter,
-                                 cfile, cifs_sb, &ctx->list, ctx);
-
-       /*
-        * If at least one write was successfully sent, then discard any rc
-        * value from the later writes. If the other write succeeds, then
-        * we'll end up returning whatever was written. If it fails, then
-        * we'll get a new rc value from that.
-        */
-       if (!list_empty(&ctx->list))
-               rc = 0;
-
-       mutex_unlock(&ctx->aio_mutex);
-
-       if (rc) {
-               kref_put(&ctx->refcount, cifs_aio_ctx_release);
-               return rc;
-       }
-
-       if (!is_sync_kiocb(iocb)) {
-               kref_put(&ctx->refcount, cifs_aio_ctx_release);
-               return -EIOCBQUEUED;
-       }
-
-       rc = wait_for_completion_killable(&ctx->done);
-       if (rc) {
-               mutex_lock(&ctx->aio_mutex);
-               ctx->rc = rc = -EINTR;
-               total_written = ctx->total_len;
-               mutex_unlock(&ctx->aio_mutex);
-       } else {
-               rc = ctx->rc;
-               total_written = ctx->total_len;
+               if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
+                       smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
+                       if (smbfile) {
+                               rc = server->ops->flush(xid, tcon, &smbfile->fid);
+                               cifsFileInfo_put(smbfile);
+                       } else
+                               cifs_dbg(FYI, "ignore fsync for file not open for write\n");
+               } else
+                       rc = server->ops->flush(xid, tcon, &smbfile->fid);
        }
 
-       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-
-       if (unlikely(!total_written))
-               return rc;
-
-       iocb->ki_pos += total_written;
-       return total_written;
+fsync_exit:
+       free_xid(xid);
+       return rc;
 }
 
-ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from)
+/*
+ * As file closes, flush all cached write data for this inode checking
+ * for write behind errors.
+ */
+int cifs_flush(struct file *file, fl_owner_t id)
 {
-       struct file *file = iocb->ki_filp;
+       struct inode *inode = file_inode(file);
+       int rc = 0;
 
-       cifs_revalidate_mapping(file->f_inode);
-       return __cifs_writev(iocb, from, true);
-}
+       if (file->f_mode & FMODE_WRITE)
+               rc = filemap_write_and_wait(inode->i_mapping);
 
-ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
-{
-       return __cifs_writev(iocb, from, false);
+       cifs_dbg(FYI, "Flush inode %p file %p rc %d\n", inode, file, rc);
+       if (rc) {
+               /* get more nuanced writeback errors */
+               rc = filemap_check_wb_err(file->f_mapping, 0);
+               trace_cifs_flush_err(inode->i_ino, rc);
+       }
+       return rc;
 }
 
 static ssize_t
@@ -3845,7 +2753,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
        struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
        ssize_t rc;
 
-       inode_lock(inode);
+       rc = netfs_start_io_write(inode);
+       if (rc < 0)
+               return rc;
+
        /*
         * We need to hold the sem to be sure nobody modifies lock list
         * with a brlock that prevents writing.
@@ -3859,13 +2770,12 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
        if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
                                     server->vals->exclusive_lock_type, 0,
                                     NULL, CIFS_WRITE_OP))
-               rc = __generic_file_write_iter(iocb, from);
+               rc = netfs_buffered_write_iter_locked(iocb, from, NULL);
        else
                rc = -EACCES;
 out:
        up_read(&cinode->lock_sem);
-       inode_unlock(inode);
-
+       netfs_end_io_write(inode);
        if (rc > 0)
                rc = generic_write_sync(iocb, rc);
        return rc;
@@ -3888,9 +2798,9 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
 
        if (CIFS_CACHE_WRITE(cinode)) {
                if (cap_unix(tcon->ses) &&
-               (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
-                 && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
-                       written = generic_file_write_iter(iocb, from);
+                   (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
+                   ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+                       written = netfs_file_write_iter(iocb, from);
                        goto out;
                }
                written = cifs_writev(iocb, from);
@@ -3902,7 +2812,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
         * affected pages because it may cause a error with mandatory locks on
         * these pages but not on the region from pos to ppos+len-1.
         */
-       written = cifs_user_writev(iocb, from);
+       written = netfs_file_write_iter(iocb, from);
        if (CIFS_CACHE_READ(cinode)) {
                /*
                 * We have read level caching and we have just sent a write
@@ -3921,449 +2831,55 @@ out:
        return written;
 }
 
-static struct cifs_readdata *cifs_readdata_alloc(work_func_t complete)
-{
-       struct cifs_readdata *rdata;
-
-       rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
-       if (rdata) {
-               kref_init(&rdata->refcount);
-               INIT_LIST_HEAD(&rdata->list);
-               init_completion(&rdata->done);
-               INIT_WORK(&rdata->work, complete);
-       }
-
-       return rdata;
-}
-
-void
-cifs_readdata_release(struct kref *refcount)
-{
-       struct cifs_readdata *rdata = container_of(refcount,
-                                       struct cifs_readdata, refcount);
-
-       if (rdata->ctx)
-               kref_put(&rdata->ctx->refcount, cifs_aio_ctx_release);
-#ifdef CONFIG_CIFS_SMB_DIRECT
-       if (rdata->mr) {
-               smbd_deregister_mr(rdata->mr);
-               rdata->mr = NULL;
-       }
-#endif
-       if (rdata->cfile)
-               cifsFileInfo_put(rdata->cfile);
-
-       kfree(rdata);
-}
-
-static void collect_uncached_read_data(struct cifs_aio_ctx *ctx);
-
-static void
-cifs_uncached_readv_complete(struct work_struct *work)
-{
-       struct cifs_readdata *rdata = container_of(work,
-                                               struct cifs_readdata, work);
-
-       complete(&rdata->done);
-       collect_uncached_read_data(rdata->ctx);
-       /* the below call can possibly free the last ref to aio ctx */
-       kref_put(&rdata->refcount, cifs_readdata_release);
-}
-
-static int cifs_resend_rdata(struct cifs_readdata *rdata,
-                       struct list_head *rdata_list,
-                       struct cifs_aio_ctx *ctx)
-{
-       unsigned int rsize;
-       struct cifs_credits credits;
-       int rc;
-       struct TCP_Server_Info *server;
-
-       /* XXX: should we pick a new channel here? */
-       server = rdata->server;
-
-       do {
-               if (rdata->cfile->invalidHandle) {
-                       rc = cifs_reopen_file(rdata->cfile, true);
-                       if (rc == -EAGAIN)
-                               continue;
-                       else if (rc)
-                               break;
-               }
-
-               /*
-                * Wait for credits to resend this rdata.
-                * Note: we are attempting to resend the whole rdata not in
-                * segments
-                */
-               do {
-                       rc = server->ops->wait_mtu_credits(server, rdata->bytes,
-                                               &rsize, &credits);
-
-                       if (rc)
-                               goto fail;
-
-                       if (rsize < rdata->bytes) {
-                               add_credits_and_wake_if(server, &credits, 0);
-                               msleep(1000);
-                       }
-               } while (rsize < rdata->bytes);
-               rdata->credits = credits;
-
-               rc = adjust_credits(server, &rdata->credits, rdata->bytes);
-               if (!rc) {
-                       if (rdata->cfile->invalidHandle)
-                               rc = -EAGAIN;
-                       else {
-#ifdef CONFIG_CIFS_SMB_DIRECT
-                               if (rdata->mr) {
-                                       rdata->mr->need_invalidate = true;
-                                       smbd_deregister_mr(rdata->mr);
-                                       rdata->mr = NULL;
-                               }
-#endif
-                               rc = server->ops->async_readv(rdata);
-                       }
-               }
-
-               /* If the read was successfully sent, we are done */
-               if (!rc) {
-                       /* Add to aio pending list */
-                       list_add_tail(&rdata->list, rdata_list);
-                       return 0;
-               }
-
-               /* Roll back credits and retry if needed */
-               add_credits_and_wake_if(server, &rdata->credits, 0);
-       } while (rc == -EAGAIN);
-
-fail:
-       kref_put(&rdata->refcount, cifs_readdata_release);
-       return rc;
-}
-
-static int
-cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
-                    struct cifs_sb_info *cifs_sb, struct list_head *rdata_list,
-                    struct cifs_aio_ctx *ctx)
-{
-       struct cifs_readdata *rdata;
-       unsigned int rsize, nsegs, max_segs = INT_MAX;
-       struct cifs_credits credits_on_stack;
-       struct cifs_credits *credits = &credits_on_stack;
-       size_t cur_len, max_len;
-       int rc;
-       pid_t pid;
-       struct TCP_Server_Info *server;
-
-       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
-
-#ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->smbd_conn)
-               max_segs = server->smbd_conn->max_frmr_depth;
-#endif
-
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
-               pid = open_file->pid;
-       else
-               pid = current->tgid;
-
-       do {
-               if (open_file->invalidHandle) {
-                       rc = cifs_reopen_file(open_file, true);
-                       if (rc == -EAGAIN)
-                               continue;
-                       else if (rc)
-                               break;
-               }
-
-               if (cifs_sb->ctx->rsize == 0)
-                       cifs_sb->ctx->rsize =
-                               server->ops->negotiate_rsize(tlink_tcon(open_file->tlink),
-                                                            cifs_sb->ctx);
-
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
-                                                  &rsize, credits);
-               if (rc)
-                       break;
-
-               max_len = min_t(size_t, len, rsize);
-
-               cur_len = cifs_limit_bvec_subset(&ctx->iter, max_len,
-                                                max_segs, &nsegs);
-               cifs_dbg(FYI, "read-to-iter len=%zx/%zx nsegs=%u/%lu/%u\n",
-                        cur_len, max_len, nsegs, ctx->iter.nr_segs, max_segs);
-               if (cur_len == 0) {
-                       rc = -EIO;
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               rdata = cifs_readdata_alloc(cifs_uncached_readv_complete);
-               if (!rdata) {
-                       add_credits_and_wake_if(server, credits, 0);
-                       rc = -ENOMEM;
-                       break;
-               }
-
-               rdata->server   = server;
-               rdata->cfile    = cifsFileInfo_get(open_file);
-               rdata->offset   = fpos;
-               rdata->bytes    = cur_len;
-               rdata->pid      = pid;
-               rdata->credits  = credits_on_stack;
-               rdata->ctx      = ctx;
-               kref_get(&ctx->refcount);
-
-               rdata->iter     = ctx->iter;
-               iov_iter_truncate(&rdata->iter, cur_len);
-
-               rc = adjust_credits(server, &rdata->credits, rdata->bytes);
-
-               if (!rc) {
-                       if (rdata->cfile->invalidHandle)
-                               rc = -EAGAIN;
-                       else
-                               rc = server->ops->async_readv(rdata);
-               }
-
-               if (rc) {
-                       add_credits_and_wake_if(server, &rdata->credits, 0);
-                       kref_put(&rdata->refcount, cifs_readdata_release);
-                       if (rc == -EAGAIN)
-                               continue;
-                       break;
-               }
-
-               list_add_tail(&rdata->list, rdata_list);
-               iov_iter_advance(&ctx->iter, cur_len);
-               fpos += cur_len;
-               len -= cur_len;
-       } while (len > 0);
-
-       return rc;
-}
-
-static void
-collect_uncached_read_data(struct cifs_aio_ctx *ctx)
+ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
-       struct cifs_readdata *rdata, *tmp;
-       struct cifs_sb_info *cifs_sb;
-       int rc;
-
-       cifs_sb = CIFS_SB(ctx->cfile->dentry->d_sb);
-
-       mutex_lock(&ctx->aio_mutex);
-
-       if (list_empty(&ctx->list)) {
-               mutex_unlock(&ctx->aio_mutex);
-               return;
-       }
-
-       rc = ctx->rc;
-       /* the loop below should proceed in the order of increasing offsets */
-again:
-       list_for_each_entry_safe(rdata, tmp, &ctx->list, list) {
-               if (!rc) {
-                       if (!try_wait_for_completion(&rdata->done)) {
-                               mutex_unlock(&ctx->aio_mutex);
-                               return;
-                       }
-
-                       if (rdata->result == -EAGAIN) {
-                               /* resend call if it's a retryable error */
-                               struct list_head tmp_list;
-                               unsigned int got_bytes = rdata->got_bytes;
-
-                               list_del_init(&rdata->list);
-                               INIT_LIST_HEAD(&tmp_list);
-
-                               if (ctx->direct_io) {
-                                       /*
-                                        * Re-use rdata as this is a
-                                        * direct I/O
-                                        */
-                                       rc = cifs_resend_rdata(
-                                               rdata,
-                                               &tmp_list, ctx);
-                               } else {
-                                       rc = cifs_send_async_read(
-                                               rdata->offset + got_bytes,
-                                               rdata->bytes - got_bytes,
-                                               rdata->cfile, cifs_sb,
-                                               &tmp_list, ctx);
-
-                                       kref_put(&rdata->refcount,
-                                               cifs_readdata_release);
-                               }
-
-                               list_splice(&tmp_list, &ctx->list);
-
-                               goto again;
-                       } else if (rdata->result)
-                               rc = rdata->result;
-
-                       /* if there was a short read -- discard anything left */
-                       if (rdata->got_bytes && rdata->got_bytes < rdata->bytes)
-                               rc = -ENODATA;
-
-                       ctx->total_len += rdata->got_bytes;
-               }
-               list_del_init(&rdata->list);
-               kref_put(&rdata->refcount, cifs_readdata_release);
-       }
-
-       /* mask nodata case */
-       if (rc == -ENODATA)
-               rc = 0;
+       ssize_t rc;
+       struct inode *inode = file_inode(iocb->ki_filp);
 
-       ctx->rc = (rc == 0) ? (ssize_t)ctx->total_len : rc;
+       if (iocb->ki_flags & IOCB_DIRECT)
+               return netfs_unbuffered_read_iter(iocb, iter);
 
-       mutex_unlock(&ctx->aio_mutex);
+       rc = cifs_revalidate_mapping(inode);
+       if (rc)
+               return rc;
 
-       if (ctx->iocb && ctx->iocb->ki_complete)
-               ctx->iocb->ki_complete(ctx->iocb, ctx->rc);
-       else
-               complete(&ctx->done);
+       return netfs_file_read_iter(iocb, iter);
 }
 
-static ssize_t __cifs_readv(
-       struct kiocb *iocb, struct iov_iter *to, bool direct)
+ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
 {
-       size_t len;
-       struct file *file = iocb->ki_filp;
-       struct cifs_sb_info *cifs_sb;
-       struct cifsFileInfo *cfile;
-       struct cifs_tcon *tcon;
-       ssize_t rc, total_read = 0;
-       loff_t offset = iocb->ki_pos;
-       struct cifs_aio_ctx *ctx;
-
-       len = iov_iter_count(to);
-       if (!len)
-               return 0;
-
-       cifs_sb = CIFS_FILE_SB(file);
-       cfile = file->private_data;
-       tcon = tlink_tcon(cfile->tlink);
-
-       if (!tcon->ses->server->ops->async_readv)
-               return -ENOSYS;
-
-       if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cifs_dbg(FYI, "attempting read on write only file instance\n");
-
-       ctx = cifs_aio_ctx_alloc();
-       if (!ctx)
-               return -ENOMEM;
-
-       ctx->pos        = offset;
-       ctx->direct_io  = direct;
-       ctx->len        = len;
-       ctx->cfile      = cifsFileInfo_get(cfile);
-       ctx->nr_pinned_pages = 0;
-
-       if (!is_sync_kiocb(iocb))
-               ctx->iocb = iocb;
-
-       if (user_backed_iter(to)) {
-               /*
-                * Extract IOVEC/UBUF-type iterators to a BVEC-type iterator as
-                * they contain references to the calling process's virtual
-                * memory layout which won't be available in an async worker
-                * thread.  This also takes a pin on every folio involved.
-                */
-               rc = netfs_extract_user_iter(to, iov_iter_count(to),
-                                            &ctx->iter, 0);
-               if (rc < 0) {
-                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-                       return rc;
-               }
-
-               ctx->nr_pinned_pages = rc;
-               ctx->bv = (void *)ctx->iter.bvec;
-               ctx->bv_need_unpin = iov_iter_extract_will_pin(to);
-               ctx->should_dirty = true;
-       } else if ((iov_iter_is_bvec(to) || iov_iter_is_kvec(to)) &&
-                  !is_sync_kiocb(iocb)) {
-               /*
-                * If the op is asynchronous, we need to copy the list attached
-                * to a BVEC/KVEC-type iterator, but we assume that the storage
-                * will be retained by the caller; in any case, we may or may
-                * not be able to pin the pages, so we don't try.
-                */
-               ctx->bv = (void *)dup_iter(&ctx->iter, to, GFP_KERNEL);
-               if (!ctx->bv) {
-                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-                       return -ENOMEM;
-               }
-       } else {
-               /*
-                * Otherwise, we just pass the iterator down as-is and rely on
-                * the caller to make sure the pages referred to by the
-                * iterator don't evaporate.
-                */
-               ctx->iter = *to;
-       }
-
-       if (direct) {
-               rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
-                                                 offset, offset + len - 1);
-               if (rc) {
-                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
-                       return -EAGAIN;
-               }
-       }
-
-       /* grab a lock here due to read response handlers can access ctx */
-       mutex_lock(&ctx->aio_mutex);
-
-       rc = cifs_send_async_read(offset, len, cfile, cifs_sb, &ctx->list, ctx);
-
-       /* if at least one read request send succeeded, then reset rc */
-       if (!list_empty(&ctx->list))
-               rc = 0;
-
-       mutex_unlock(&ctx->aio_mutex);
-
-       if (rc) {
-               kref_put(&ctx->refcount, cifs_aio_ctx_release);
-               return rc;
-       }
+       struct inode *inode = file_inode(iocb->ki_filp);
+       struct cifsInodeInfo *cinode = CIFS_I(inode);
+       ssize_t written;
+       int rc;
 
-       if (!is_sync_kiocb(iocb)) {
-               kref_put(&ctx->refcount, cifs_aio_ctx_release);
-               return -EIOCBQUEUED;
+       if (iocb->ki_filp->f_flags & O_DIRECT) {
+               written = netfs_unbuffered_write_iter(iocb, from);
+               if (written > 0 && CIFS_CACHE_READ(cinode)) {
+                       cifs_zap_mapping(inode);
+                       cifs_dbg(FYI,
+                                "Set no oplock for inode=%p after a write operation\n",
+                                inode);
+                       cinode->oplock = 0;
+               }
+               return written;
        }
 
-       rc = wait_for_completion_killable(&ctx->done);
-       if (rc) {
-               mutex_lock(&ctx->aio_mutex);
-               ctx->rc = rc = -EINTR;
-               total_read = ctx->total_len;
-               mutex_unlock(&ctx->aio_mutex);
-       } else {
-               rc = ctx->rc;
-               total_read = ctx->total_len;
-       }
+       written = cifs_get_writer(cinode);
+       if (written)
+               return written;
 
-       kref_put(&ctx->refcount, cifs_aio_ctx_release);
+       written = netfs_file_write_iter(iocb, from);
 
-       if (total_read) {
-               iocb->ki_pos += total_read;
-               return total_read;
+       if (!CIFS_CACHE_WRITE(CIFS_I(inode))) {
+               rc = filemap_fdatawrite(inode->i_mapping);
+               if (rc)
+                       cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
+                                rc, inode);
        }
-       return rc;
-}
 
-ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
-{
-       return __cifs_readv(iocb, to, true);
-}
-
-ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
-{
-       return __cifs_readv(iocb, to, false);
+       cifs_put_writer(cinode);
+       return written;
 }
 
 ssize_t
@@ -4386,140 +2902,52 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
         * pos+len-1.
         */
        if (!CIFS_CACHE_READ(cinode))
-               return cifs_user_readv(iocb, to);
+               return netfs_unbuffered_read_iter(iocb, to);
 
        if (cap_unix(tcon->ses) &&
            (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
-           ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
-               return generic_file_read_iter(iocb, to);
+           ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+               if (iocb->ki_flags & IOCB_DIRECT)
+                       return netfs_unbuffered_read_iter(iocb, to);
+               return netfs_buffered_read_iter(iocb, to);
+       }
 
        /*
         * We need to hold the sem to be sure nobody modifies lock list
         * with a brlock that prevents reading.
         */
-       down_read(&cinode->lock_sem);
-       if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(to),
-                                    tcon->ses->server->vals->shared_lock_type,
-                                    0, NULL, CIFS_READ_OP))
-               rc = generic_file_read_iter(iocb, to);
-       up_read(&cinode->lock_sem);
-       return rc;
-}
-
-static ssize_t
-cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
-{
-       int rc = -EACCES;
-       unsigned int bytes_read = 0;
-       unsigned int total_read;
-       unsigned int current_read_size;
-       unsigned int rsize;
-       struct cifs_sb_info *cifs_sb;
-       struct cifs_tcon *tcon;
-       struct TCP_Server_Info *server;
-       unsigned int xid;
-       char *cur_offset;
-       struct cifsFileInfo *open_file;
-       struct cifs_io_parms io_parms = {0};
-       int buf_type = CIFS_NO_BUFFER;
-       __u32 pid;
-
-       xid = get_xid();
-       cifs_sb = CIFS_FILE_SB(file);
-
-       /* FIXME: set up handlers for larger reads and/or convert to async */
-       rsize = min_t(unsigned int, cifs_sb->ctx->rsize, CIFSMaxBufSize);
-
-       if (file->private_data == NULL) {
-               rc = -EBADF;
-               free_xid(xid);
-               return rc;
-       }
-       open_file = file->private_data;
-       tcon = tlink_tcon(open_file->tlink);
-       server = cifs_pick_channel(tcon->ses);
-
-       if (!server->ops->sync_read) {
-               free_xid(xid);
-               return -ENOSYS;
-       }
-
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
-               pid = open_file->pid;
-       else
-               pid = current->tgid;
-
-       if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-               cifs_dbg(FYI, "attempting read on write only file instance\n");
-
-       for (total_read = 0, cur_offset = read_data; read_size > total_read;
-            total_read += bytes_read, cur_offset += bytes_read) {
-               do {
-                       current_read_size = min_t(uint, read_size - total_read,
-                                                 rsize);
-                       /*
-                        * For windows me and 9x we do not want to request more
-                        * than it negotiated since it will refuse the read
-                        * then.
-                        */
-                       if (!(tcon->ses->capabilities &
-                               tcon->ses->server->vals->cap_large_files)) {
-                               current_read_size = min_t(uint,
-                                       current_read_size, CIFSMaxBufSize);
-                       }
-                       if (open_file->invalidHandle) {
-                               rc = cifs_reopen_file(open_file, true);
-                               if (rc != 0)
-                                       break;
-                       }
-                       io_parms.pid = pid;
-                       io_parms.tcon = tcon;
-                       io_parms.offset = *offset;
-                       io_parms.length = current_read_size;
-                       io_parms.server = server;
-                       rc = server->ops->sync_read(xid, &open_file->fid, &io_parms,
-                                                   &bytes_read, &cur_offset,
-                                                   &buf_type);
-               } while (rc == -EAGAIN);
-
-               if (rc || (bytes_read == 0)) {
-                       if (total_read) {
-                               break;
-                       } else {
-                               free_xid(xid);
-                               return rc;
-                       }
-               } else {
-                       cifs_stats_bytes_read(tcon, total_read);
-                       *offset += bytes_read;
-               }
+       if (iocb->ki_flags & IOCB_DIRECT) {
+               rc = netfs_start_io_direct(inode);
+               if (rc < 0)
+                       goto out;
+               down_read(&cinode->lock_sem);
+               if (!cifs_find_lock_conflict(
+                           cfile, iocb->ki_pos, iov_iter_count(to),
+                           tcon->ses->server->vals->shared_lock_type,
+                           0, NULL, CIFS_READ_OP))
+                       rc = netfs_unbuffered_read_iter_locked(iocb, to);
+               up_read(&cinode->lock_sem);
+               netfs_end_io_direct(inode);
+       } else {
+               rc = netfs_start_io_read(inode);
+               if (rc < 0)
+                       goto out;
+               down_read(&cinode->lock_sem);
+               if (!cifs_find_lock_conflict(
+                           cfile, iocb->ki_pos, iov_iter_count(to),
+                           tcon->ses->server->vals->shared_lock_type,
+                           0, NULL, CIFS_READ_OP))
+                       rc = filemap_read(iocb, to, 0);
+               up_read(&cinode->lock_sem);
+               netfs_end_io_read(inode);
        }
-       free_xid(xid);
-       return total_read;
+out:
+       return rc;
 }
 
-/*
- * If the page is mmap'ed into a process' page tables, then we need to make
- * sure that it doesn't change while being written back.
- */
 static vm_fault_t cifs_page_mkwrite(struct vm_fault *vmf)
 {
-       struct folio *folio = page_folio(vmf->page);
-
-       /* Wait for the folio to be written to the cache before we allow it to
-        * be modified.  We then assume the entire folio will need writing back.
-        */
-#ifdef CONFIG_CIFS_FSCACHE
-       if (folio_test_fscache(folio) &&
-           folio_wait_fscache_killable(folio) < 0)
-               return VM_FAULT_RETRY;
-#endif
-
-       folio_wait_writeback(folio);
-
-       if (folio_lock_killable(folio) < 0)
-               return VM_FAULT_RETRY;
-       return VM_FAULT_LOCKED;
+       return netfs_page_mkwrite(vmf, NULL);
 }
 
 static const struct vm_operations_struct cifs_file_vm_ops = {
@@ -4565,290 +2993,6 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
        return rc;
 }
 
-/*
- * Unlock a bunch of folios in the pagecache.
- */
-static void cifs_unlock_folios(struct address_space *mapping, pgoff_t first, pgoff_t last)
-{
-       struct folio *folio;
-       XA_STATE(xas, &mapping->i_pages, first);
-
-       rcu_read_lock();
-       xas_for_each(&xas, folio, last) {
-               folio_unlock(folio);
-       }
-       rcu_read_unlock();
-}
-
-static void cifs_readahead_complete(struct work_struct *work)
-{
-       struct cifs_readdata *rdata = container_of(work,
-                                                  struct cifs_readdata, work);
-       struct folio *folio;
-       pgoff_t last;
-       bool good = rdata->result == 0 || (rdata->result == -EAGAIN && rdata->got_bytes);
-
-       XA_STATE(xas, &rdata->mapping->i_pages, rdata->offset / PAGE_SIZE);
-
-       if (good)
-               cifs_readahead_to_fscache(rdata->mapping->host,
-                                         rdata->offset, rdata->bytes);
-
-       if (iov_iter_count(&rdata->iter) > 0)
-               iov_iter_zero(iov_iter_count(&rdata->iter), &rdata->iter);
-
-       last = (rdata->offset + rdata->bytes - 1) / PAGE_SIZE;
-
-       rcu_read_lock();
-       xas_for_each(&xas, folio, last) {
-               if (good) {
-                       flush_dcache_folio(folio);
-                       folio_mark_uptodate(folio);
-               }
-               folio_unlock(folio);
-       }
-       rcu_read_unlock();
-
-       kref_put(&rdata->refcount, cifs_readdata_release);
-}
-
-static void cifs_readahead(struct readahead_control *ractl)
-{
-       struct cifsFileInfo *open_file = ractl->file->private_data;
-       struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(ractl->file);
-       struct TCP_Server_Info *server;
-       unsigned int xid, nr_pages, cache_nr_pages = 0;
-       unsigned int ra_pages;
-       pgoff_t next_cached = ULONG_MAX, ra_index;
-       bool caching = fscache_cookie_enabled(cifs_inode_cookie(ractl->mapping->host)) &&
-               cifs_inode_cookie(ractl->mapping->host)->cache_priv;
-       bool check_cache = caching;
-       pid_t pid;
-       int rc = 0;
-
-       /* Note that readahead_count() lags behind our dequeuing of pages from
-        * the ractl, wo we have to keep track for ourselves.
-        */
-       ra_pages = readahead_count(ractl);
-       ra_index = readahead_index(ractl);
-
-       xid = get_xid();
-
-       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
-               pid = open_file->pid;
-       else
-               pid = current->tgid;
-
-       server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
-
-       cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n",
-                __func__, ractl->file, ractl->mapping, ra_pages);
-
-       /*
-        * Chop the readahead request up into rsize-sized read requests.
-        */
-       while ((nr_pages = ra_pages)) {
-               unsigned int i, rsize;
-               struct cifs_readdata *rdata;
-               struct cifs_credits credits_on_stack;
-               struct cifs_credits *credits = &credits_on_stack;
-               struct folio *folio;
-               pgoff_t fsize;
-
-               /*
-                * Find out if we have anything cached in the range of
-                * interest, and if so, where the next chunk of cached data is.
-                */
-               if (caching) {
-                       if (check_cache) {
-                               rc = cifs_fscache_query_occupancy(
-                                       ractl->mapping->host, ra_index, nr_pages,
-                                       &next_cached, &cache_nr_pages);
-                               if (rc < 0)
-                                       caching = false;
-                               check_cache = false;
-                       }
-
-                       if (ra_index == next_cached) {
-                               /*
-                                * TODO: Send a whole batch of pages to be read
-                                * by the cache.
-                                */
-                               folio = readahead_folio(ractl);
-                               fsize = folio_nr_pages(folio);
-                               ra_pages -= fsize;
-                               ra_index += fsize;
-                               if (cifs_readpage_from_fscache(ractl->mapping->host,
-                                                              &folio->page) < 0) {
-                                       /*
-                                        * TODO: Deal with cache read failure
-                                        * here, but for the moment, delegate
-                                        * that to readpage.
-                                        */
-                                       caching = false;
-                               }
-                               folio_unlock(folio);
-                               next_cached += fsize;
-                               cache_nr_pages -= fsize;
-                               if (cache_nr_pages == 0)
-                                       check_cache = true;
-                               continue;
-                       }
-               }
-
-               if (open_file->invalidHandle) {
-                       rc = cifs_reopen_file(open_file, true);
-                       if (rc) {
-                               if (rc == -EAGAIN)
-                                       continue;
-                               break;
-                       }
-               }
-
-               if (cifs_sb->ctx->rsize == 0)
-                       cifs_sb->ctx->rsize =
-                               server->ops->negotiate_rsize(tlink_tcon(open_file->tlink),
-                                                            cifs_sb->ctx);
-
-               rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
-                                                  &rsize, credits);
-               if (rc)
-                       break;
-               nr_pages = min_t(size_t, rsize / PAGE_SIZE, ra_pages);
-               if (next_cached != ULONG_MAX)
-                       nr_pages = min_t(size_t, nr_pages, next_cached - ra_index);
-
-               /*
-                * Give up immediately if rsize is too small to read an entire
-                * page. The VFS will fall back to readpage. We should never
-                * reach this point however since we set ra_pages to 0 when the
-                * rsize is smaller than a cache page.
-                */
-               if (unlikely(!nr_pages)) {
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               rdata = cifs_readdata_alloc(cifs_readahead_complete);
-               if (!rdata) {
-                       /* best to give up if we're out of mem */
-                       add_credits_and_wake_if(server, credits, 0);
-                       break;
-               }
-
-               rdata->offset   = ra_index * PAGE_SIZE;
-               rdata->bytes    = nr_pages * PAGE_SIZE;
-               rdata->cfile    = cifsFileInfo_get(open_file);
-               rdata->server   = server;
-               rdata->mapping  = ractl->mapping;
-               rdata->pid      = pid;
-               rdata->credits  = credits_on_stack;
-
-               for (i = 0; i < nr_pages; i++) {
-                       if (!readahead_folio(ractl))
-                               WARN_ON(1);
-               }
-               ra_pages -= nr_pages;
-               ra_index += nr_pages;
-
-               iov_iter_xarray(&rdata->iter, ITER_DEST, &rdata->mapping->i_pages,
-                               rdata->offset, rdata->bytes);
-
-               rc = adjust_credits(server, &rdata->credits, rdata->bytes);
-               if (!rc) {
-                       if (rdata->cfile->invalidHandle)
-                               rc = -EAGAIN;
-                       else
-                               rc = server->ops->async_readv(rdata);
-               }
-
-               if (rc) {
-                       add_credits_and_wake_if(server, &rdata->credits, 0);
-                       cifs_unlock_folios(rdata->mapping,
-                                          rdata->offset / PAGE_SIZE,
-                                          (rdata->offset + rdata->bytes - 1) / PAGE_SIZE);
-                       /* Fallback to the readpage in error/reconnect cases */
-                       kref_put(&rdata->refcount, cifs_readdata_release);
-                       break;
-               }
-
-               kref_put(&rdata->refcount, cifs_readdata_release);
-       }
-
-       free_xid(xid);
-}
-
-/*
- * cifs_readpage_worker must be called with the page pinned
- */
-static int cifs_readpage_worker(struct file *file, struct page *page,
-       loff_t *poffset)
-{
-       struct inode *inode = file_inode(file);
-       struct timespec64 atime, mtime;
-       char *read_data;
-       int rc;
-
-       /* Is the page cached? */
-       rc = cifs_readpage_from_fscache(inode, page);
-       if (rc == 0)
-               goto read_complete;
-
-       read_data = kmap(page);
-       /* for reads over a certain size could initiate async read ahead */
-
-       rc = cifs_read(file, read_data, PAGE_SIZE, poffset);
-
-       if (rc < 0)
-               goto io_error;
-       else
-               cifs_dbg(FYI, "Bytes read %d\n", rc);
-
-       /* we do not want atime to be less than mtime, it broke some apps */
-       atime = inode_set_atime_to_ts(inode, current_time(inode));
-       mtime = inode_get_mtime(inode);
-       if (timespec64_compare(&atime, &mtime) < 0)
-               inode_set_atime_to_ts(inode, inode_get_mtime(inode));
-
-       if (PAGE_SIZE > rc)
-               memset(read_data + rc, 0, PAGE_SIZE - rc);
-
-       flush_dcache_page(page);
-       SetPageUptodate(page);
-       rc = 0;
-
-io_error:
-       kunmap(page);
-
-read_complete:
-       unlock_page(page);
-       return rc;
-}
-
-static int cifs_read_folio(struct file *file, struct folio *folio)
-{
-       struct page *page = &folio->page;
-       loff_t offset = page_file_offset(page);
-       int rc = -EACCES;
-       unsigned int xid;
-
-       xid = get_xid();
-
-       if (file->private_data == NULL) {
-               rc = -EBADF;
-               free_xid(xid);
-               return rc;
-       }
-
-       cifs_dbg(FYI, "read_folio %p at offset %d 0x%x\n",
-                page, (int)offset, (int)offset);
-
-       rc = cifs_readpage_worker(file, page, &offset);
-
-       free_xid(xid);
-       return rc;
-}
-
 static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
 {
        struct cifsFileInfo *open_file;
@@ -4896,123 +3040,6 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
                return true;
 }
 
-static int cifs_write_begin(struct file *file, struct address_space *mapping,
-                       loff_t pos, unsigned len,
-                       struct page **pagep, void **fsdata)
-{
-       int oncethru = 0;
-       pgoff_t index = pos >> PAGE_SHIFT;
-       loff_t offset = pos & (PAGE_SIZE - 1);
-       loff_t page_start = pos & PAGE_MASK;
-       loff_t i_size;
-       struct page *page;
-       int rc = 0;
-
-       cifs_dbg(FYI, "write_begin from %lld len %d\n", (long long)pos, len);
-
-start:
-       page = grab_cache_page_write_begin(mapping, index);
-       if (!page) {
-               rc = -ENOMEM;
-               goto out;
-       }
-
-       if (PageUptodate(page))
-               goto out;
-
-       /*
-        * If we write a full page it will be up to date, no need to read from
-        * the server. If the write is short, we'll end up doing a sync write
-        * instead.
-        */
-       if (len == PAGE_SIZE)
-               goto out;
-
-       /*
-        * optimize away the read when we have an oplock, and we're not
-        * expecting to use any of the data we'd be reading in. That
-        * is, when the page lies beyond the EOF, or straddles the EOF
-        * and the write will cover all of the existing data.
-        */
-       if (CIFS_CACHE_READ(CIFS_I(mapping->host))) {
-               i_size = i_size_read(mapping->host);
-               if (page_start >= i_size ||
-                   (offset == 0 && (pos + len) >= i_size)) {
-                       zero_user_segments(page, 0, offset,
-                                          offset + len,
-                                          PAGE_SIZE);
-                       /*
-                        * PageChecked means that the parts of the page
-                        * to which we're not writing are considered up
-                        * to date. Once the data is copied to the
-                        * page, it can be set uptodate.
-                        */
-                       SetPageChecked(page);
-                       goto out;
-               }
-       }
-
-       if ((file->f_flags & O_ACCMODE) != O_WRONLY && !oncethru) {
-               /*
-                * might as well read a page, it is fast enough. If we get
-                * an error, we don't need to return it. cifs_write_end will
-                * do a sync write instead since PG_uptodate isn't set.
-                */
-               cifs_readpage_worker(file, page, &page_start);
-               put_page(page);
-               oncethru = 1;
-               goto start;
-       } else {
-               /* we could try using another file handle if there is one -
-                  but how would we lock it to prevent close of that handle
-                  racing with this read? In any case
-                  this will be written out by write_end so is fine */
-       }
-out:
-       *pagep = page;
-       return rc;
-}
-
-static bool cifs_release_folio(struct folio *folio, gfp_t gfp)
-{
-       if (folio_test_private(folio))
-               return 0;
-       if (folio_test_fscache(folio)) {
-               if (current_is_kswapd() || !(gfp & __GFP_FS))
-                       return false;
-               folio_wait_fscache(folio);
-       }
-       fscache_note_page_release(cifs_inode_cookie(folio->mapping->host));
-       return true;
-}
-
-static void cifs_invalidate_folio(struct folio *folio, size_t offset,
-                                size_t length)
-{
-       folio_wait_fscache(folio);
-}
-
-static int cifs_launder_folio(struct folio *folio)
-{
-       int rc = 0;
-       loff_t range_start = folio_pos(folio);
-       loff_t range_end = range_start + folio_size(folio);
-       struct writeback_control wbc = {
-               .sync_mode = WB_SYNC_ALL,
-               .nr_to_write = 0,
-               .range_start = range_start,
-               .range_end = range_end,
-       };
-
-       cifs_dbg(FYI, "Launder page: %lu\n", folio->index);
-
-       if (folio_clear_dirty_for_io(folio))
-               rc = cifs_writepage_locked(&folio->page, &wbc);
-
-       folio_wait_fscache(folio);
-       return rc;
-}
-
 void cifs_oplock_break(struct work_struct *work)
 {
        struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
@@ -5102,25 +3129,6 @@ out:
        cifs_done_oplock_break(cinode);
 }
 
-/*
- * The presence of cifs_direct_io() in the address space ops vector
- * allowes open() O_DIRECT flags which would have failed otherwise.
- *
- * In the non-cached mode (mount with cache=none), we shunt off direct read and write requests
- * so this method should never be called.
- *
- * Direct IO is not yet supported in the cached mode.
- */
-static ssize_t
-cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter)
-{
-        /*
-         * FIXME
-         * Eventually need to support direct IO for non forcedirectio mounts
-         */
-        return -EINVAL;
-}
-
 static int cifs_swap_activate(struct swap_info_struct *sis,
                              struct file *swap_file, sector_t *span)
 {
@@ -5182,22 +3190,19 @@ static void cifs_swap_deactivate(struct file *file)
 }
 
 const struct address_space_operations cifs_addr_ops = {
-       .read_folio = cifs_read_folio,
-       .readahead = cifs_readahead,
-       .writepages = cifs_writepages,
-       .write_begin = cifs_write_begin,
-       .write_end = cifs_write_end,
-       .dirty_folio = netfs_dirty_folio,
-       .release_folio = cifs_release_folio,
-       .direct_IO = cifs_direct_io,
-       .invalidate_folio = cifs_invalidate_folio,
-       .launder_folio = cifs_launder_folio,
-       .migrate_folio = filemap_migrate_folio,
+       .read_folio     = netfs_read_folio,
+       .readahead      = netfs_readahead,
+       .writepages     = netfs_writepages,
+       .dirty_folio    = netfs_dirty_folio,
+       .release_folio  = netfs_release_folio,
+       .direct_IO      = noop_direct_IO,
+       .invalidate_folio = netfs_invalidate_folio,
+       .migrate_folio  = filemap_migrate_folio,
        /*
         * TODO: investigate and if useful we could add an is_dirty_writeback
         * helper if needed
         */
-       .swap_activate = cifs_swap_activate,
+       .swap_activate  = cifs_swap_activate,
        .swap_deactivate = cifs_swap_deactivate,
 };
 
@@ -5207,13 +3212,10 @@ const struct address_space_operations cifs_addr_ops = {
  * to leave cifs_readahead out of the address space operations.
  */
 const struct address_space_operations cifs_addr_ops_smallbuf = {
-       .read_folio = cifs_read_folio,
-       .writepages = cifs_writepages,
-       .write_begin = cifs_write_begin,
-       .write_end = cifs_write_end,
-       .dirty_folio = netfs_dirty_folio,
-       .release_folio = cifs_release_folio,
-       .invalidate_folio = cifs_invalidate_folio,
-       .launder_folio = cifs_launder_folio,
-       .migrate_folio = filemap_migrate_folio,
+       .read_folio     = netfs_read_folio,
+       .writepages     = netfs_writepages,
+       .dirty_folio    = netfs_dirty_folio,
+       .release_folio  = netfs_release_folio,
+       .invalidate_folio = netfs_invalidate_folio,
+       .migrate_folio  = filemap_migrate_folio,
 };
index 1a895e6243ee9aaf21fc8405893ce52ed14303a2..01424a5cdb990bcb6e8502a2485d85cf773c04a2 100644 (file)
@@ -170,112 +170,3 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
                cifsi->netfs.cache = NULL;
        }
 }
-
-/*
- * Fallback page reading interface.
- */
-static int fscache_fallback_read_page(struct inode *inode, struct page *page)
-{
-       struct netfs_cache_resources cres;
-       struct fscache_cookie *cookie = cifs_inode_cookie(inode);
-       struct iov_iter iter;
-       struct bio_vec bvec;
-       int ret;
-
-       memset(&cres, 0, sizeof(cres));
-       bvec_set_page(&bvec, page, PAGE_SIZE, 0);
-       iov_iter_bvec(&iter, ITER_DEST, &bvec, 1, PAGE_SIZE);
-
-       ret = fscache_begin_read_operation(&cres, cookie);
-       if (ret < 0)
-               return ret;
-
-       ret = fscache_read(&cres, page_offset(page), &iter, NETFS_READ_HOLE_FAIL,
-                          NULL, NULL);
-       fscache_end_operation(&cres);
-       return ret;
-}
-
-/*
- * Fallback page writing interface.
- */
-static int fscache_fallback_write_pages(struct inode *inode, loff_t start, size_t len,
-                                       bool no_space_allocated_yet)
-{
-       struct netfs_cache_resources cres;
-       struct fscache_cookie *cookie = cifs_inode_cookie(inode);
-       struct iov_iter iter;
-       int ret;
-
-       memset(&cres, 0, sizeof(cres));
-       iov_iter_xarray(&iter, ITER_SOURCE, &inode->i_mapping->i_pages, start, len);
-
-       ret = fscache_begin_write_operation(&cres, cookie);
-       if (ret < 0)
-               return ret;
-
-       ret = cres.ops->prepare_write(&cres, &start, &len, len, i_size_read(inode),
-                                     no_space_allocated_yet);
-       if (ret == 0)
-               ret = fscache_write(&cres, start, &iter, NULL, NULL);
-       fscache_end_operation(&cres);
-       return ret;
-}
-
-/*
- * Retrieve a page from FS-Cache
- */
-int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
-{
-       int ret;
-
-       cifs_dbg(FYI, "%s: (fsc:%p, p:%p, i:0x%p\n",
-                __func__, cifs_inode_cookie(inode), page, inode);
-
-       ret = fscache_fallback_read_page(inode, page);
-       if (ret < 0)
-               return ret;
-
-       /* Read completed synchronously */
-       SetPageUptodate(page);
-       return 0;
-}
-
-void __cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len)
-{
-       cifs_dbg(FYI, "%s: (fsc: %p, p: %llx, l: %zx, i: %p)\n",
-                __func__, cifs_inode_cookie(inode), pos, len, inode);
-
-       fscache_fallback_write_pages(inode, pos, len, true);
-}
-
-/*
- * Query the cache occupancy.
- */
-int __cifs_fscache_query_occupancy(struct inode *inode,
-                                  pgoff_t first, unsigned int nr_pages,
-                                  pgoff_t *_data_first,
-                                  unsigned int *_data_nr_pages)
-{
-       struct netfs_cache_resources cres;
-       struct fscache_cookie *cookie = cifs_inode_cookie(inode);
-       loff_t start, data_start;
-       size_t len, data_len;
-       int ret;
-
-       ret = fscache_begin_read_operation(&cres, cookie);
-       if (ret < 0)
-               return ret;
-
-       start = first * PAGE_SIZE;
-       len = nr_pages * PAGE_SIZE;
-       ret = cres.ops->query_occupancy(&cres, start, len, PAGE_SIZE,
-                                       &data_start, &data_len);
-       if (ret == 0) {
-               *_data_first = data_start / PAGE_SIZE;
-               *_data_nr_pages = len / PAGE_SIZE;
-       }
-
-       fscache_end_operation(&cres);
-       return ret;
-}
index 1f2ea9f5cc9a8a5f900a5a5367cf093d54f2f80d..f06cb24f5f3cfce0cb275b65766aac785fa4cffe 100644 (file)
@@ -74,41 +74,6 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags
                           i_size_read(inode), flags);
 }
 
-extern int __cifs_fscache_query_occupancy(struct inode *inode,
-                                         pgoff_t first, unsigned int nr_pages,
-                                         pgoff_t *_data_first,
-                                         unsigned int *_data_nr_pages);
-
-static inline int cifs_fscache_query_occupancy(struct inode *inode,
-                                              pgoff_t first, unsigned int nr_pages,
-                                              pgoff_t *_data_first,
-                                              unsigned int *_data_nr_pages)
-{
-       if (!cifs_inode_cookie(inode))
-               return -ENOBUFS;
-       return __cifs_fscache_query_occupancy(inode, first, nr_pages,
-                                             _data_first, _data_nr_pages);
-}
-
-extern int __cifs_readpage_from_fscache(struct inode *pinode, struct page *ppage);
-extern void __cifs_readahead_to_fscache(struct inode *pinode, loff_t pos, size_t len);
-
-
-static inline int cifs_readpage_from_fscache(struct inode *inode,
-                                            struct page *page)
-{
-       if (cifs_inode_cookie(inode))
-               return __cifs_readpage_from_fscache(inode, page);
-       return -ENOBUFS;
-}
-
-static inline void cifs_readahead_to_fscache(struct inode *inode,
-                                            loff_t pos, size_t len)
-{
-       if (cifs_inode_cookie(inode))
-               __cifs_readahead_to_fscache(inode, pos, len);
-}
-
 static inline bool cifs_fscache_enabled(struct inode *inode)
 {
        return fscache_cookie_enabled(cifs_inode_cookie(inode));
@@ -131,25 +96,6 @@ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { re
 static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {}
 static inline bool cifs_fscache_enabled(struct inode *inode) { return false; }
 
-static inline int cifs_fscache_query_occupancy(struct inode *inode,
-                                              pgoff_t first, unsigned int nr_pages,
-                                              pgoff_t *_data_first,
-                                              unsigned int *_data_nr_pages)
-{
-       *_data_first = ULONG_MAX;
-       *_data_nr_pages = 0;
-       return -ENOBUFS;
-}
-
-static inline int
-cifs_readpage_from_fscache(struct inode *inode, struct page *page)
-{
-       return -ENOBUFS;
-}
-
-static inline
-void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {}
-
 #endif /* CONFIG_CIFS_FSCACHE */
 
 #endif /* _CIFS_FSCACHE_H */
index 60afab5c83d410a9c5122d5f4826ade67cb93dee..e8bfeea23660e47a6cf2e59544bafdfa0f913b16 100644 (file)
 #include "cached_dir.h"
 #include "reparse.h"
 
+/*
+ * Set parameters for the netfs library
+ */
+static void cifs_set_netfs_context(struct inode *inode)
+{
+       struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+
+       netfs_inode_init(&cifs_i->netfs, &cifs_req_ops, true);
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
+               __set_bit(NETFS_ICTX_WRITETHROUGH, &cifs_i->netfs.flags);
+}
+
 static void cifs_set_ops(struct inode *inode)
 {
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
+       struct netfs_inode *ictx = netfs_inode(inode);
 
        switch (inode->i_mode & S_IFMT) {
        case S_IFREG:
                inode->i_op = &cifs_file_inode_ops;
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+                       set_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags);
                        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
                                inode->i_fop = &cifs_file_direct_nobrl_ops;
                        else
@@ -57,6 +72,7 @@ static void cifs_set_ops(struct inode *inode)
                        inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
                else
                        inode->i_data.a_ops = &cifs_addr_ops;
+               mapping_set_large_folios(inode->i_mapping);
                break;
        case S_IFDIR:
                if (IS_AUTOMOUNT(inode)) {
@@ -221,8 +237,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
 
        if (fattr->cf_flags & CIFS_FATTR_JUNCTION)
                inode->i_flags |= S_AUTOMOUNT;
-       if (inode->i_state & I_NEW)
+       if (inode->i_state & I_NEW) {
+               cifs_set_netfs_context(inode);
                cifs_set_ops(inode);
+       }
        return 0;
 }
 
@@ -2431,24 +2449,6 @@ cifs_dentry_needs_reval(struct dentry *dentry)
        return false;
 }
 
-/*
- * Zap the cache. Called when invalid_mapping flag is set.
- */
-int
-cifs_invalidate_mapping(struct inode *inode)
-{
-       int rc = 0;
-
-       if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
-               rc = invalidate_inode_pages2(inode->i_mapping);
-               if (rc)
-                       cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",
-                                __func__, inode, rc);
-       }
-
-       return rc;
-}
-
 /**
  * cifs_wait_bit_killable - helper for functions that are sleeping on bit locks
  *
@@ -2485,9 +2485,12 @@ cifs_revalidate_mapping(struct inode *inode)
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
                        goto skip_invalidate;
 
-               rc = cifs_invalidate_mapping(inode);
-               if (rc)
+               rc = filemap_invalidate_inode(inode, true, 0, LLONG_MAX);
+               if (rc) {
+                       cifs_dbg(VFS, "%s: invalidate inode %p failed with rc %d\n",
+                                __func__, inode, rc);
                        set_bit(CIFS_INO_INVALID_MAPPING, flags);
+               }
        }
 
 skip_invalidate:
index 28f0b7d19d534b18bff680bb739247889ac7675b..ef18cd30f66c5a875f60f2d5fccda38c643c37b2 100644 (file)
@@ -217,8 +217,8 @@ smb2_get_credits(struct mid_q_entry *mid)
 }
 
 static int
-smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
-                     unsigned int *num, struct cifs_credits *credits)
+smb2_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
+                     size_t *num, struct cifs_credits *credits)
 {
        int rc = 0;
        unsigned int scredits, in_flight;
@@ -4490,7 +4490,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
        unsigned int cur_off;
        unsigned int cur_page_idx;
        unsigned int pad_len;
-       struct cifs_readdata *rdata = mid->callback_data;
+       struct cifs_io_subrequest *rdata = mid->callback_data;
        struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
        int length;
        bool use_rdma_mr = false;
@@ -4592,7 +4592,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 
                /* Copy the data to the output I/O iterator. */
                rdata->result = cifs_copy_pages_to_iter(pages, pages_len,
-                                                       cur_off, &rdata->iter);
+                                                       cur_off, &rdata->subreq.io_iter);
                if (rdata->result != 0) {
                        if (is_offloaded)
                                mid->mid_state = MID_RESPONSE_MALFORMED;
@@ -4606,7 +4606,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                /* read response payload is in buf */
                WARN_ONCE(pages && !xa_empty(pages),
                          "read data can be either in buf or in pages");
-               length = copy_to_iter(buf + data_offset, data_len, &rdata->iter);
+               length = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter);
                if (length < 0)
                        return length;
                rdata->got_bytes = data_len;
index a5efce03cb58e2d995862f8c3b0cc081f8beed5b..993ac36c3d585ae7fa740300e60d27b481ebebe4 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/uuid.h>
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
+#include <linux/netfs.h>
+#include <trace/events/netfs.h>
 #include "cifsglob.h"
 #include "cifsacl.h"
 #include "cifsproto.h"
@@ -4391,7 +4393,7 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
  */
 static int
 smb2_new_read_req(void **buf, unsigned int *total_len,
-       struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
+       struct cifs_io_parms *io_parms, struct cifs_io_subrequest *rdata,
        unsigned int remaining_bytes, int request_type)
 {
        int rc = -EACCES;
@@ -4419,10 +4421,12 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
        req->Length = cpu_to_le32(io_parms->length);
        req->Offset = cpu_to_le64(io_parms->offset);
 
-       trace_smb3_read_enter(0 /* xid */,
-                       io_parms->persistent_fid,
-                       io_parms->tcon->tid, io_parms->tcon->ses->Suid,
-                       io_parms->offset, io_parms->length);
+       trace_smb3_read_enter(rdata ? rdata->rreq->debug_id : 0,
+                             rdata ? rdata->subreq.debug_index : 0,
+                             rdata ? rdata->xid : 0,
+                             io_parms->persistent_fid,
+                             io_parms->tcon->tid, io_parms->tcon->ses->Suid,
+                             io_parms->offset, io_parms->length);
 #ifdef CONFIG_CIFS_SMB_DIRECT
        /*
         * If we want to do a RDMA write, fill in and append
@@ -4432,7 +4436,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
                struct smbd_buffer_descriptor_v1 *v1;
                bool need_invalidate = server->dialect == SMB30_PROT_ID;
 
-               rdata->mr = smbd_register_mr(server->smbd_conn, &rdata->iter,
+               rdata->mr = smbd_register_mr(server->smbd_conn, &rdata->subreq.io_iter,
                                             true, need_invalidate);
                if (!rdata->mr)
                        return -EAGAIN;
@@ -4483,8 +4487,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
 static void
 smb2_readv_callback(struct mid_q_entry *mid)
 {
-       struct cifs_readdata *rdata = mid->callback_data;
-       struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+       struct cifs_io_subrequest *rdata = mid->callback_data;
+       struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
        struct TCP_Server_Info *server = rdata->server;
        struct smb2_hdr *shdr =
                                (struct smb2_hdr *)rdata->iov[0].iov_base;
@@ -4492,17 +4496,17 @@ smb2_readv_callback(struct mid_q_entry *mid)
        struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], .rq_nvec = 1 };
 
        if (rdata->got_bytes) {
-               rqst.rq_iter      = rdata->iter;
-               rqst.rq_iter_size = iov_iter_count(&rdata->iter);
+               rqst.rq_iter      = rdata->subreq.io_iter;
+               rqst.rq_iter_size = iov_iter_count(&rdata->subreq.io_iter);
        }
 
        WARN_ONCE(rdata->server != mid->server,
                  "rdata server %p != mid server %p",
                  rdata->server, mid->server);
 
-       cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
+       cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%zu\n",
                 __func__, mid->mid, mid->mid_state, rdata->result,
-                rdata->bytes);
+                rdata->subreq.len);
 
        switch (mid->mid_state) {
        case MID_RESPONSE_RECEIVED:
@@ -4512,7 +4516,6 @@ smb2_readv_callback(struct mid_q_entry *mid)
                if (server->sign && !mid->decrypted) {
                        int rc;
 
-                       iov_iter_revert(&rqst.rq_iter, rdata->got_bytes);
                        iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
                        rc = smb2_verify_signature(&rqst, server);
                        if (rc)
@@ -4553,24 +4556,40 @@ smb2_readv_callback(struct mid_q_entry *mid)
 #endif
        if (rdata->result && rdata->result != -ENODATA) {
                cifs_stats_fail_inc(tcon, SMB2_READ_HE);
-               trace_smb3_read_err(0 /* xid */,
-                                   rdata->cfile->fid.persistent_fid,
-                                   tcon->tid, tcon->ses->Suid, rdata->offset,
-                                   rdata->bytes, rdata->result);
+               trace_smb3_read_err(rdata->rreq->debug_id,
+                                   rdata->subreq.debug_index,
+                                   rdata->xid,
+                                   rdata->req->cfile->fid.persistent_fid,
+                                   tcon->tid, tcon->ses->Suid, rdata->subreq.start,
+                                   rdata->subreq.len, rdata->result);
        } else
-               trace_smb3_read_done(0 /* xid */,
-                                    rdata->cfile->fid.persistent_fid,
+               trace_smb3_read_done(rdata->rreq->debug_id,
+                                    rdata->subreq.debug_index,
+                                    rdata->xid,
+                                    rdata->req->cfile->fid.persistent_fid,
                                     tcon->tid, tcon->ses->Suid,
-                                    rdata->offset, rdata->got_bytes);
+                                    rdata->subreq.start, rdata->got_bytes);
 
-       queue_work(cifsiod_wq, &rdata->work);
+       if (rdata->result == -ENODATA) {
+               /* We may have got an EOF error because fallocate
+                * failed to enlarge the file.
+                */
+               if (rdata->subreq.start < rdata->subreq.rreq->i_size)
+                       rdata->result = 0;
+       }
+       if (rdata->result == 0 || rdata->result == -EAGAIN)
+               iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
+       rdata->credits.value = 0;
+       netfs_subreq_terminated(&rdata->subreq,
+                               (rdata->result == 0 || rdata->result == -EAGAIN) ?
+                               rdata->got_bytes : rdata->result, true);
        release_mid(mid);
        add_credits(server, &credits, 0);
 }
 
 /* smb2_async_readv - send an async read, and set up mid to handle result */
 int
-smb2_async_readv(struct cifs_readdata *rdata)
+smb2_async_readv(struct cifs_io_subrequest *rdata)
 {
        int rc, flags = 0;
        char *buf;
@@ -4579,22 +4598,22 @@ smb2_async_readv(struct cifs_readdata *rdata)
        struct smb_rqst rqst = { .rq_iov = rdata->iov,
                                 .rq_nvec = 1 };
        struct TCP_Server_Info *server;
-       struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
        unsigned int total_len;
        int credit_request;
 
-       cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
-                __func__, rdata->offset, rdata->bytes);
+       cifs_dbg(FYI, "%s: offset=%llu bytes=%zu\n",
+                __func__, rdata->subreq.start, rdata->subreq.len);
 
        if (!rdata->server)
                rdata->server = cifs_pick_channel(tcon->ses);
 
-       io_parms.tcon = tlink_tcon(rdata->cfile->tlink);
+       io_parms.tcon = tlink_tcon(rdata->req->cfile->tlink);
        io_parms.server = server = rdata->server;
-       io_parms.offset = rdata->offset;
-       io_parms.length = rdata->bytes;
-       io_parms.persistent_fid = rdata->cfile->fid.persistent_fid;
-       io_parms.volatile_fid = rdata->cfile->fid.volatile_fid;
+       io_parms.offset = rdata->subreq.start;
+       io_parms.length = rdata->subreq.len;
+       io_parms.persistent_fid = rdata->req->cfile->fid.persistent_fid;
+       io_parms.volatile_fid = rdata->req->cfile->fid.volatile_fid;
        io_parms.pid = rdata->pid;
 
        rc = smb2_new_read_req(
@@ -4611,7 +4630,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
        shdr = (struct smb2_hdr *)buf;
 
        if (rdata->credits.value > 0) {
-               shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
+               shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->subreq.len,
                                                SMB2_MAX_BUFFER_SIZE));
                credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
                if (server->credits >= server->max_credits)
@@ -4621,22 +4640,22 @@ smb2_async_readv(struct cifs_readdata *rdata)
                                min_t(int, server->max_credits -
                                                server->credits, credit_request));
 
-               rc = adjust_credits(server, &rdata->credits, rdata->bytes);
+               rc = adjust_credits(server, &rdata->credits, rdata->subreq.len);
                if (rc)
                        goto async_readv_out;
 
                flags |= CIFS_HAS_CREDITS;
        }
 
-       kref_get(&rdata->refcount);
        rc = cifs_call_async(server, &rqst,
                             cifs_readv_receive, smb2_readv_callback,
                             smb3_handle_read_data, rdata, flags,
                             &rdata->credits);
        if (rc) {
-               kref_put(&rdata->refcount, cifs_readdata_release);
                cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
-               trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
+               trace_smb3_read_err(rdata->rreq->debug_id,
+                                   rdata->subreq.debug_index,
+                                   rdata->xid, io_parms.persistent_fid,
                                    io_parms.tcon->tid,
                                    io_parms.tcon->ses->Suid,
                                    io_parms.offset, io_parms.length, rc);
@@ -4687,22 +4706,23 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
                if (rc != -ENODATA) {
                        cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
                        cifs_dbg(VFS, "Send error in read = %d\n", rc);
-                       trace_smb3_read_err(xid,
+                       trace_smb3_read_err(0, 0, xid,
                                            req->PersistentFileId,
                                            io_parms->tcon->tid, ses->Suid,
                                            io_parms->offset, io_parms->length,
                                            rc);
                } else
-                       trace_smb3_read_done(xid, req->PersistentFileId, io_parms->tcon->tid,
+                       trace_smb3_read_done(0, 0, xid,
+                                            req->PersistentFileId, io_parms->tcon->tid,
                                             ses->Suid, io_parms->offset, 0);
                free_rsp_buf(resp_buftype, rsp_iov.iov_base);
                cifs_small_buf_release(req);
                return rc == -ENODATA ? 0 : rc;
        } else
-               trace_smb3_read_done(xid,
-                                   req->PersistentFileId,
-                                   io_parms->tcon->tid, ses->Suid,
-                                   io_parms->offset, io_parms->length);
+               trace_smb3_read_done(0, 0, xid,
+                                    req->PersistentFileId,
+                                    io_parms->tcon->tid, ses->Suid,
+                                    io_parms->offset, io_parms->length);
 
        cifs_small_buf_release(req);
 
@@ -4735,12 +4755,13 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
 static void
 smb2_writev_callback(struct mid_q_entry *mid)
 {
-       struct cifs_writedata *wdata = mid->callback_data;
-       struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct cifs_io_subrequest *wdata = mid->callback_data;
+       struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
        struct TCP_Server_Info *server = wdata->server;
-       unsigned int written;
        struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
        struct cifs_credits credits = { .value = 0, .instance = 0 };
+       ssize_t result = 0;
+       size_t written;
 
        WARN_ONCE(wdata->server != mid->server,
                  "wdata server %p != mid server %p",
@@ -4750,8 +4771,8 @@ smb2_writev_callback(struct mid_q_entry *mid)
        case MID_RESPONSE_RECEIVED:
                credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
                credits.instance = server->reconnect_instance;
-               wdata->result = smb2_check_receive(mid, server, 0);
-               if (wdata->result != 0)
+               result = smb2_check_receive(mid, server, 0);
+               if (result != 0)
                        break;
 
                written = le32_to_cpu(rsp->DataLength);
@@ -4761,24 +4782,25 @@ smb2_writev_callback(struct mid_q_entry *mid)
                 * client. OS/2 servers are known to set incorrect
                 * CountHigh values.
                 */
-               if (written > wdata->bytes)
+               if (written > wdata->subreq.len)
                        written &= 0xFFFF;
 
-               if (written < wdata->bytes)
+               if (written < wdata->subreq.len)
                        wdata->result = -ENOSPC;
                else
-                       wdata->bytes = written;
+                       wdata->subreq.len = written;
+               iov_iter_advance(&wdata->subreq.io_iter, written);
                break;
        case MID_REQUEST_SUBMITTED:
        case MID_RETRY_NEEDED:
-               wdata->result = -EAGAIN;
+               result = -EAGAIN;
                break;
        case MID_RESPONSE_MALFORMED:
                credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
                credits.instance = server->reconnect_instance;
                fallthrough;
        default:
-               wdata->result = -EIO;
+               result = -EIO;
                break;
        }
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -4794,44 +4816,44 @@ smb2_writev_callback(struct mid_q_entry *mid)
                wdata->mr = NULL;
        }
 #endif
-       if (wdata->result) {
+       if (result) {
                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
-               trace_smb3_write_err(0 /* no xid */,
-                                    wdata->cfile->fid.persistent_fid,
-                                    tcon->tid, tcon->ses->Suid, wdata->offset,
-                                    wdata->bytes, wdata->result);
+               trace_smb3_write_err(wdata->xid,
+                                    wdata->req->cfile->fid.persistent_fid,
+                                    tcon->tid, tcon->ses->Suid, wdata->subreq.start,
+                                    wdata->subreq.len, wdata->result);
                if (wdata->result == -ENOSPC)
                        pr_warn_once("Out of space writing to %s\n",
                                     tcon->tree_name);
        } else
                trace_smb3_write_done(0 /* no xid */,
-                                     wdata->cfile->fid.persistent_fid,
+                                     wdata->req->cfile->fid.persistent_fid,
                                      tcon->tid, tcon->ses->Suid,
-                                     wdata->offset, wdata->bytes);
+                                     wdata->subreq.start, wdata->subreq.len);
 
-       queue_work(cifsiod_wq, &wdata->work);
+       wdata->credits.value = 0;
+       cifs_write_subrequest_terminated(wdata, result ?: written, true);
        release_mid(mid);
        add_credits(server, &credits, 0);
 }
 
 /* smb2_async_writev - send an async write, and set up mid to handle result */
-int
-smb2_async_writev(struct cifs_writedata *wdata,
-                 void (*release)(struct kref *kref))
+void
+smb2_async_writev(struct cifs_io_subrequest *wdata)
 {
        int rc = -EACCES, flags = 0;
        struct smb2_write_req *req = NULL;
        struct smb2_hdr *shdr;
-       struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
+       struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
        struct TCP_Server_Info *server = wdata->server;
        struct kvec iov[1];
        struct smb_rqst rqst = { };
-       unsigned int total_len;
+       unsigned int total_len, xid = wdata->xid;
        struct cifs_io_parms _io_parms;
        struct cifs_io_parms *io_parms = NULL;
        int credit_request;
 
-       if (!wdata->server || wdata->replay)
+       if (!wdata->server || test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags))
                server = wdata->server = cifs_pick_channel(tcon->ses);
 
        /*
@@ -4841,10 +4863,10 @@ smb2_async_writev(struct cifs_writedata *wdata,
        _io_parms = (struct cifs_io_parms) {
                .tcon = tcon,
                .server = server,
-               .offset = wdata->offset,
-               .length = wdata->bytes,
-               .persistent_fid = wdata->cfile->fid.persistent_fid,
-               .volatile_fid = wdata->cfile->fid.volatile_fid,
+               .offset = wdata->subreq.start,
+               .length = wdata->subreq.len,
+               .persistent_fid = wdata->req->cfile->fid.persistent_fid,
+               .volatile_fid = wdata->req->cfile->fid.volatile_fid,
                .pid = wdata->pid,
        };
        io_parms = &_io_parms;
@@ -4852,7 +4874,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
        rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
                                 (void **) &req, &total_len);
        if (rc)
-               return rc;
+               goto out;
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -4870,7 +4892,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
                                offsetof(struct smb2_write_req, Buffer));
        req->RemainingBytes = 0;
 
-       trace_smb3_write_enter(0 /* xid */,
+       trace_smb3_write_enter(wdata->xid,
                               io_parms->persistent_fid,
                               io_parms->tcon->tid,
                               io_parms->tcon->ses->Suid,
@@ -4884,10 +4906,10 @@ smb2_async_writev(struct cifs_writedata *wdata,
         */
        if (smb3_use_rdma_offload(io_parms)) {
                struct smbd_buffer_descriptor_v1 *v1;
-               size_t data_size = iov_iter_count(&wdata->iter);
+               size_t data_size = iov_iter_count(&wdata->subreq.io_iter);
                bool need_invalidate = server->dialect == SMB30_PROT_ID;
 
-               wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->iter,
+               wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->subreq.io_iter,
                                             false, need_invalidate);
                if (!wdata->mr) {
                        rc = -EAGAIN;
@@ -4914,9 +4936,9 @@ smb2_async_writev(struct cifs_writedata *wdata,
 
        rqst.rq_iov = iov;
        rqst.rq_nvec = 1;
-       rqst.rq_iter = wdata->iter;
+       rqst.rq_iter = wdata->subreq.io_iter;
        rqst.rq_iter_size = iov_iter_count(&rqst.rq_iter);
-       if (wdata->replay)
+       if (test_bit(NETFS_SREQ_RETRYING, &wdata->subreq.flags))
                smb2_set_replay(server, &rqst);
 #ifdef CONFIG_CIFS_SMB_DIRECT
        if (wdata->mr)
@@ -4934,7 +4956,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
 #endif
 
        if (wdata->credits.value > 0) {
-               shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
+               shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->subreq.len,
                                                    SMB2_MAX_BUFFER_SIZE));
                credit_request = le16_to_cpu(shdr->CreditCharge) + 8;
                if (server->credits >= server->max_credits)
@@ -4951,25 +4973,27 @@ smb2_async_writev(struct cifs_writedata *wdata,
                flags |= CIFS_HAS_CREDITS;
        }
 
-       kref_get(&wdata->refcount);
        rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
                             wdata, flags, &wdata->credits);
-
+       /* Can't touch wdata if rc == 0 */
        if (rc) {
-               trace_smb3_write_err(0 /* no xid */,
+               trace_smb3_write_err(xid,
                                     io_parms->persistent_fid,
                                     io_parms->tcon->tid,
                                     io_parms->tcon->ses->Suid,
                                     io_parms->offset,
                                     io_parms->length,
                                     rc);
-               kref_put(&wdata->refcount, release);
                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
        }
 
 async_writev_out:
        cifs_small_buf_release(req);
-       return rc;
+out:
+       if (rc) {
+               add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
+               cifs_write_subrequest_terminated(wdata, rc, true);
+       }
 }
 
 /*
index 2fccf0d4f53d2743153f973b9c31c5c700e27170..5c458ab3b05a442282377f2dc2c9f88b6e33809c 100644 (file)
@@ -145,7 +145,7 @@ struct durable_context_v2 {
 } __packed;
 
 struct create_durable_v2 {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct durable_context_v2 dcontext;
 } __packed;
@@ -167,7 +167,7 @@ struct durable_reconnect_context_v2_rsp {
 } __packed;
 
 struct create_durable_handle_reconnect_v2 {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct durable_reconnect_context_v2 dcontext;
        __u8   Pad[4];
@@ -175,7 +175,7 @@ struct create_durable_handle_reconnect_v2 {
 
 /* See MS-SMB2 2.2.13.2.5 */
 struct crt_twarp_ctxt {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8    Name[8];
        __le64  Timestamp;
 
@@ -183,12 +183,12 @@ struct crt_twarp_ctxt {
 
 /* See MS-SMB2 2.2.13.2.9 */
 struct crt_query_id_ctxt {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8    Name[8];
 } __packed;
 
 struct crt_sd_ctxt {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8    Name[8];
        struct smb3_sd sd;
 } __packed;
@@ -415,7 +415,7 @@ struct smb2_posix_info_parsed {
 };
 
 struct smb2_create_ea_ctx {
-       struct create_context ctx;
+       struct create_context_hdr ctx;
        __u8 name[8];
        struct smb2_file_full_ea_info ea;
 } __packed;
index 732169d8a67a32eab76ac5950a3f8c8d30a8b18e..b208232b12a24da69908d8f66085dac0b0d5d085 100644 (file)
@@ -210,11 +210,10 @@ extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
 extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
                            u64 persistent_fid, u64 volatile_fid,
                            __le64 *uniqueid);
-extern int smb2_async_readv(struct cifs_readdata *rdata);
+extern int smb2_async_readv(struct cifs_io_subrequest *rdata);
 extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
                     unsigned int *nbytes, char **buf, int *buf_type);
-extern int smb2_async_writev(struct cifs_writedata *wdata,
-                            void (*release)(struct kref *kref));
+extern void smb2_async_writev(struct cifs_io_subrequest *wdata);
 extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
                      unsigned int *nbytes, struct kvec *iov, int n_vec);
 extern int SMB2_echo(struct TCP_Server_Info *server);
index 604e52876cd2d98e9a86941b0c527dbe6d8abe6a..af97389e983e0651df680b504c41bcadeff7cb58 100644 (file)
@@ -85,6 +85,62 @@ smb3_tcon_ref_traces;
 
 /* For logging errors in read or write */
 DECLARE_EVENT_CLASS(smb3_rw_err_class,
+       TP_PROTO(unsigned int rreq_debug_id,
+                unsigned int rreq_debug_index,
+                unsigned int xid,
+                __u64  fid,
+                __u32  tid,
+                __u64  sesid,
+                __u64  offset,
+                __u32  len,
+                int    rc),
+       TP_ARGS(rreq_debug_id, rreq_debug_index,
+               xid, fid, tid, sesid, offset, len, rc),
+       TP_STRUCT__entry(
+               __field(unsigned int, rreq_debug_id)
+               __field(unsigned int, rreq_debug_index)
+               __field(unsigned int, xid)
+               __field(__u64, fid)
+               __field(__u32, tid)
+               __field(__u64, sesid)
+               __field(__u64, offset)
+               __field(__u32, len)
+               __field(int, rc)
+       ),
+       TP_fast_assign(
+               __entry->rreq_debug_id = rreq_debug_id;
+               __entry->rreq_debug_index = rreq_debug_index;
+               __entry->xid = xid;
+               __entry->fid = fid;
+               __entry->tid = tid;
+               __entry->sesid = sesid;
+               __entry->offset = offset;
+               __entry->len = len;
+               __entry->rc = rc;
+       ),
+       TP_printk("\tR=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d",
+                 __entry->rreq_debug_id, __entry->rreq_debug_index,
+                 __entry->xid, __entry->sesid, __entry->tid, __entry->fid,
+                 __entry->offset, __entry->len, __entry->rc)
+)
+
+#define DEFINE_SMB3_RW_ERR_EVENT(name)          \
+DEFINE_EVENT(smb3_rw_err_class, smb3_##name,    \
+       TP_PROTO(unsigned int rreq_debug_id,    \
+                unsigned int rreq_debug_index,         \
+                unsigned int xid,                      \
+                __u64  fid,                            \
+                __u32  tid,                            \
+                __u64  sesid,                          \
+                __u64  offset,                         \
+                __u32  len,                            \
+                int    rc),                            \
+       TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len, rc))
+
+DEFINE_SMB3_RW_ERR_EVENT(read_err);
+
+/* For logging errors in other file I/O ops */
+DECLARE_EVENT_CLASS(smb3_other_err_class,
        TP_PROTO(unsigned int xid,
                __u64   fid,
                __u32   tid,
@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class,
                __entry->offset, __entry->len, __entry->rc)
 )
 
-#define DEFINE_SMB3_RW_ERR_EVENT(name)          \
-DEFINE_EVENT(smb3_rw_err_class, smb3_##name,    \
+#define DEFINE_SMB3_OTHER_ERR_EVENT(name)      \
+DEFINE_EVENT(smb3_other_err_class, smb3_##name, \
        TP_PROTO(unsigned int xid,              \
                __u64   fid,                    \
                __u32   tid,                    \
@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name,    \
                int     rc),                    \
        TP_ARGS(xid, fid, tid, sesid, offset, len, rc))
 
-DEFINE_SMB3_RW_ERR_EVENT(write_err);
-DEFINE_SMB3_RW_ERR_EVENT(read_err);
-DEFINE_SMB3_RW_ERR_EVENT(query_dir_err);
-DEFINE_SMB3_RW_ERR_EVENT(zero_err);
-DEFINE_SMB3_RW_ERR_EVENT(falloc_err);
+DEFINE_SMB3_OTHER_ERR_EVENT(write_err);
+DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
+DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
+DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
 
 
 /* For logging successful read or write */
 DECLARE_EVENT_CLASS(smb3_rw_done_class,
+       TP_PROTO(unsigned int rreq_debug_id,
+                unsigned int rreq_debug_index,
+                unsigned int xid,
+                __u64  fid,
+                __u32  tid,
+                __u64  sesid,
+                __u64  offset,
+                __u32  len),
+       TP_ARGS(rreq_debug_id, rreq_debug_index,
+               xid, fid, tid, sesid, offset, len),
+       TP_STRUCT__entry(
+               __field(unsigned int, rreq_debug_id)
+               __field(unsigned int, rreq_debug_index)
+               __field(unsigned int, xid)
+               __field(__u64, fid)
+               __field(__u32, tid)
+               __field(__u64, sesid)
+               __field(__u64, offset)
+               __field(__u32, len)
+       ),
+       TP_fast_assign(
+               __entry->rreq_debug_id = rreq_debug_id;
+               __entry->rreq_debug_index = rreq_debug_index;
+               __entry->xid = xid;
+               __entry->fid = fid;
+               __entry->tid = tid;
+               __entry->sesid = sesid;
+               __entry->offset = offset;
+               __entry->len = len;
+       ),
+       TP_printk("R=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x",
+                 __entry->rreq_debug_id, __entry->rreq_debug_index,
+                 __entry->xid, __entry->sesid, __entry->tid, __entry->fid,
+                 __entry->offset, __entry->len)
+)
+
+#define DEFINE_SMB3_RW_DONE_EVENT(name)         \
+DEFINE_EVENT(smb3_rw_done_class, smb3_##name,   \
+       TP_PROTO(unsigned int rreq_debug_id,    \
+                unsigned int rreq_debug_index, \
+                unsigned int xid,              \
+               __u64   fid,                    \
+               __u32   tid,                    \
+               __u64   sesid,                  \
+               __u64   offset,                 \
+               __u32   len),                   \
+       TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len))
+
+DEFINE_SMB3_RW_DONE_EVENT(read_enter);
+DEFINE_SMB3_RW_DONE_EVENT(read_done);
+
+/* For logging successful other op */
+DECLARE_EVENT_CLASS(smb3_other_done_class,
        TP_PROTO(unsigned int xid,
                __u64   fid,
                __u32   tid,
@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class,
                __entry->offset, __entry->len)
 )
 
-#define DEFINE_SMB3_RW_DONE_EVENT(name)         \
-DEFINE_EVENT(smb3_rw_done_class, smb3_##name,   \
+#define DEFINE_SMB3_OTHER_DONE_EVENT(name)         \
+DEFINE_EVENT(smb3_other_done_class, smb3_##name,   \
        TP_PROTO(unsigned int xid,              \
                __u64   fid,                    \
                __u32   tid,                    \
@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name,   \
                __u32   len),                   \
        TP_ARGS(xid, fid, tid, sesid, offset, len))
 
-DEFINE_SMB3_RW_DONE_EVENT(write_enter);
-DEFINE_SMB3_RW_DONE_EVENT(read_enter);
-DEFINE_SMB3_RW_DONE_EVENT(query_dir_enter);
-DEFINE_SMB3_RW_DONE_EVENT(zero_enter);
-DEFINE_SMB3_RW_DONE_EVENT(falloc_enter);
-DEFINE_SMB3_RW_DONE_EVENT(write_done);
-DEFINE_SMB3_RW_DONE_EVENT(read_done);
-DEFINE_SMB3_RW_DONE_EVENT(query_dir_done);
-DEFINE_SMB3_RW_DONE_EVENT(zero_done);
-DEFINE_SMB3_RW_DONE_EVENT(falloc_done);
+DEFINE_SMB3_OTHER_DONE_EVENT(write_enter);
+DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_enter);
+DEFINE_SMB3_OTHER_DONE_EVENT(zero_enter);
+DEFINE_SMB3_OTHER_DONE_EVENT(falloc_enter);
+DEFINE_SMB3_OTHER_DONE_EVENT(write_done);
+DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_done);
+DEFINE_SMB3_OTHER_DONE_EVENT(zero_done);
+DEFINE_SMB3_OTHER_DONE_EVENT(falloc_done);
 
 /* For logging successful set EOF (truncate) */
 DECLARE_EVENT_CLASS(smb3_eof_class,
index ddf1a3aafee5c6f1e4f9c6ed4db54c48fcc8a84a..012b9bd069952cec16bec71f03a594d53016450c 100644 (file)
@@ -691,8 +691,8 @@ wait_for_compound_request(struct TCP_Server_Info *server, int num,
 }
 
 int
-cifs_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
-                     unsigned int *num, struct cifs_credits *credits)
+cifs_wait_mtu_credits(struct TCP_Server_Info *server, size_t size,
+                     size_t *num, struct cifs_credits *credits)
 {
        *num = size;
        credits->value = 0;
@@ -1692,7 +1692,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 static int
 cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 {
-       struct cifs_readdata *rdata = mid->callback_data;
+       struct cifs_io_subrequest *rdata = mid->callback_data;
 
        return  __cifs_readv_discard(server, mid, rdata->result);
 }
@@ -1702,13 +1702,13 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 {
        int length, len;
        unsigned int data_offset, data_len;
-       struct cifs_readdata *rdata = mid->callback_data;
+       struct cifs_io_subrequest *rdata = mid->callback_data;
        char *buf = server->smallbuf;
        unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
        bool use_rdma_mr = false;
 
-       cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%u\n",
-                __func__, mid->mid, rdata->offset, rdata->bytes);
+       cifs_dbg(FYI, "%s: mid=%llu offset=%llu bytes=%zu\n",
+                __func__, mid->mid, rdata->subreq.start, rdata->subreq.len);
 
        /*
         * read the rest of READ_RSP header (sans Data array), or whatever we
@@ -1813,8 +1813,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                length = data_len; /* An RDMA read is already done. */
        else
 #endif
-               length = cifs_read_iter_from_socket(server, &rdata->iter,
+       {
+               length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter,
                                                    data_len);
+               iov_iter_revert(&rdata->subreq.io_iter, data_len);
+       }
        if (length > 0)
                rdata->got_bytes += length;
        server->total_read += length;
index 202ff912815604bd7b22700fc5ff598dd0a769ac..8d10be1fe18a8d68077d97d3471129527152a1e6 100644 (file)
@@ -1171,12 +1171,15 @@ struct smb2_server_client_notification {
 #define SMB2_CREATE_FLAG_REPARSEPOINT 0x01
 
 struct create_context {
-       __le32 Next;
-       __le16 NameOffset;
-       __le16 NameLength;
-       __le16 Reserved;
-       __le16 DataOffset;
-       __le32 DataLength;
+       /* New members must be added within the struct_group() macro below. */
+       __struct_group(create_context_hdr, hdr, __packed,
+               __le32 Next;
+               __le16 NameOffset;
+               __le16 NameLength;
+               __le16 Reserved;
+               __le16 DataOffset;
+               __le32 DataLength;
+       );
        __u8 Buffer[];
 } __packed;
 
@@ -1222,7 +1225,7 @@ struct smb2_create_rsp {
 } __packed;
 
 struct create_posix {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8    Name[16];
        __le32  Mode;
        __u32   Reserved;
@@ -1230,7 +1233,7 @@ struct create_posix {
 
 /* See MS-SMB2 2.2.13.2.3 and MS-SMB2 2.2.13.2.4 */
 struct create_durable {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        union {
                __u8  Reserved[16];
@@ -1243,14 +1246,14 @@ struct create_durable {
 
 /* See MS-SMB2 2.2.13.2.5 */
 struct create_mxac_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le64 Timestamp;
 } __packed;
 
 /* See MS-SMB2 2.2.14.2.5 */
 struct create_mxac_rsp {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le32 QueryStatus;
        __le32 MaximalAccess;
@@ -1286,13 +1289,13 @@ struct lease_context_v2 {
 } __packed;
 
 struct create_lease {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct lease_context lcontext;
 } __packed;
 
 struct create_lease_v2 {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct lease_context_v2 lcontext;
        __u8   Pad[4];
@@ -1300,7 +1303,7 @@ struct create_lease_v2 {
 
 /* See MS-SMB2 2.2.14.2.9 */
 struct create_disk_id_rsp {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le64 DiskFileId;
        __le64 VolumeId;
@@ -1309,7 +1312,7 @@ struct create_disk_id_rsp {
 
 /* See MS-SMB2 2.2.13.2.13 */
 struct create_app_inst_id {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8 Name[16];
        __le32 StructureSize; /* Must be 20 */
        __u16 Reserved;
@@ -1318,7 +1321,7 @@ struct create_app_inst_id {
 
 /* See MS-SMB2 2.2.13.2.15 */
 struct create_app_inst_id_vers {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8 Name[16];
        __le32 StructureSize; /* Must be 24 */
        __u16 Reserved;
index 4978edfb15f9d7fe452e14c7ffd03b820d2165e9..b9d9116fc2b3f2848cefd1f8aeea18f2d0708a10 100644 (file)
@@ -207,9 +207,9 @@ static void opinfo_add(struct oplock_info *opinfo)
 {
        struct ksmbd_inode *ci = opinfo->o_fp->f_ci;
 
-       write_lock(&ci->m_lock);
+       down_write(&ci->m_lock);
        list_add_rcu(&opinfo->op_entry, &ci->m_op_list);
-       write_unlock(&ci->m_lock);
+       up_write(&ci->m_lock);
 }
 
 static void opinfo_del(struct oplock_info *opinfo)
@@ -221,9 +221,9 @@ static void opinfo_del(struct oplock_info *opinfo)
                lease_del_list(opinfo);
                write_unlock(&lease_list_lock);
        }
-       write_lock(&ci->m_lock);
+       down_write(&ci->m_lock);
        list_del_rcu(&opinfo->op_entry);
-       write_unlock(&ci->m_lock);
+       up_write(&ci->m_lock);
 }
 
 static unsigned long opinfo_count(struct ksmbd_file *fp)
@@ -526,21 +526,18 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
         * Compare lease key and client_guid to know request from same owner
         * of same client
         */
-       read_lock(&ci->m_lock);
+       down_read(&ci->m_lock);
        list_for_each_entry(opinfo, &ci->m_op_list, op_entry) {
                if (!opinfo->is_lease || !opinfo->conn)
                        continue;
-               read_unlock(&ci->m_lock);
                lease = opinfo->o_lease;
 
                ret = compare_guid_key(opinfo, client_guid, lctx->lease_key);
                if (ret) {
                        m_opinfo = opinfo;
                        /* skip upgrading lease about breaking lease */
-                       if (atomic_read(&opinfo->breaking_cnt)) {
-                               read_lock(&ci->m_lock);
+                       if (atomic_read(&opinfo->breaking_cnt))
                                continue;
-                       }
 
                        /* upgrading lease */
                        if ((atomic_read(&ci->op_count) +
@@ -570,9 +567,8 @@ static struct oplock_info *same_client_has_lease(struct ksmbd_inode *ci,
                                lease_none_upgrade(opinfo, lctx->req_state);
                        }
                }
-               read_lock(&ci->m_lock);
        }
-       read_unlock(&ci->m_lock);
+       up_read(&ci->m_lock);
 
        return m_opinfo;
 }
@@ -613,13 +609,23 @@ static int oplock_break_pending(struct oplock_info *opinfo, int req_op_level)
 
                if (opinfo->op_state == OPLOCK_CLOSING)
                        return -ENOENT;
-               else if (!opinfo->is_lease && opinfo->level <= req_op_level)
-                       return 1;
+               else if (opinfo->level <= req_op_level) {
+                       if (opinfo->is_lease &&
+                           opinfo->o_lease->state !=
+                            (SMB2_LEASE_HANDLE_CACHING_LE |
+                             SMB2_LEASE_READ_CACHING_LE))
+                               return 1;
+               }
        }
 
-       if (!opinfo->is_lease && opinfo->level <= req_op_level) {
-               wake_up_oplock_break(opinfo);
-               return 1;
+       if (opinfo->level <= req_op_level) {
+               if (opinfo->is_lease &&
+                   opinfo->o_lease->state !=
+                    (SMB2_LEASE_HANDLE_CACHING_LE |
+                     SMB2_LEASE_READ_CACHING_LE)) {
+                       wake_up_oplock_break(opinfo);
+                       return 1;
+               }
        }
        return 0;
 }
@@ -887,7 +893,6 @@ static int oplock_break(struct oplock_info *brk_opinfo, int req_op_level)
                struct lease *lease = brk_opinfo->o_lease;
 
                atomic_inc(&brk_opinfo->breaking_cnt);
-
                err = oplock_break_pending(brk_opinfo, req_op_level);
                if (err)
                        return err < 0 ? err : 0;
@@ -1105,7 +1110,7 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
        if (!p_ci)
                return;
 
-       read_lock(&p_ci->m_lock);
+       down_read(&p_ci->m_lock);
        list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
                if (opinfo->conn == NULL || !opinfo->is_lease)
                        continue;
@@ -1123,13 +1128,11 @@ void smb_send_parent_lease_break_noti(struct ksmbd_file *fp,
                                continue;
                        }
 
-                       read_unlock(&p_ci->m_lock);
                        oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
                        opinfo_conn_put(opinfo);
-                       read_lock(&p_ci->m_lock);
                }
        }
-       read_unlock(&p_ci->m_lock);
+       up_read(&p_ci->m_lock);
 
        ksmbd_inode_put(p_ci);
 }
@@ -1150,7 +1153,7 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
        if (!p_ci)
                return;
 
-       read_lock(&p_ci->m_lock);
+       down_read(&p_ci->m_lock);
        list_for_each_entry(opinfo, &p_ci->m_op_list, op_entry) {
                if (opinfo->conn == NULL || !opinfo->is_lease)
                        continue;
@@ -1164,13 +1167,11 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp)
                                atomic_dec(&opinfo->conn->r_count);
                                continue;
                        }
-                       read_unlock(&p_ci->m_lock);
                        oplock_break(opinfo, SMB2_OPLOCK_LEVEL_NONE);
                        opinfo_conn_put(opinfo);
-                       read_lock(&p_ci->m_lock);
                }
        }
-       read_unlock(&p_ci->m_lock);
+       up_read(&p_ci->m_lock);
 
        ksmbd_inode_put(p_ci);
 }
@@ -1200,7 +1201,9 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid,
 
        /* Only v2 leases handle the directory */
        if (S_ISDIR(file_inode(fp->filp)->i_mode)) {
-               if (!lctx || lctx->version != 2)
+               if (!lctx || lctx->version != 2 ||
+                   (lctx->flags != SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE &&
+                    !lctx->epoch))
                        return 0;
        }
 
@@ -1465,8 +1468,9 @@ void create_lease_buf(u8 *rbuf, struct lease *lease)
                buf->lcontext.LeaseFlags = lease->flags;
                buf->lcontext.Epoch = cpu_to_le16(lease->epoch);
                buf->lcontext.LeaseState = lease->state;
-               memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key,
-                      SMB2_LEASE_KEY_SIZE);
+               if (lease->flags == SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE)
+                       memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key,
+                              SMB2_LEASE_KEY_SIZE);
                buf->ccontext.DataOffset = cpu_to_le16(offsetof
                                (struct create_lease_v2, lcontext));
                buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
@@ -1525,8 +1529,9 @@ struct lease_ctx_info *parse_lease_state(void *open_req)
                lreq->flags = lc->lcontext.LeaseFlags;
                lreq->epoch = lc->lcontext.Epoch;
                lreq->duration = lc->lcontext.LeaseDuration;
-               memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
-                               SMB2_LEASE_KEY_SIZE);
+               if (lreq->flags == SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE)
+                       memcpy(lreq->parent_lease_key, lc->lcontext.ParentLeaseKey,
+                              SMB2_LEASE_KEY_SIZE);
                lreq->version = 2;
        } else {
                struct create_lease *lc = (struct create_lease *)cc;
index 355824151c2d88194b7013c2ffeabc074fbe6b87..b6c5a8ea388791d2c6fbb2fc599cc3284f6ff3d3 100644 (file)
@@ -1926,7 +1926,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
        struct ksmbd_session *sess = work->sess;
        char *treename = NULL, *name = NULL;
        struct ksmbd_tree_conn_status status;
-       struct ksmbd_share_config *share;
+       struct ksmbd_share_config *share = NULL;
        int rc = -EINVAL;
 
        WORK_BUFFERS(work, req, rsp);
@@ -1988,7 +1988,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
        write_unlock(&sess->tree_conns_lock);
        rsp->StructureSize = cpu_to_le16(16);
 out_err1:
-       if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE &&
+       if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE && share &&
            test_share_config_flag(share,
                                   KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY))
                rsp->Capabilities = SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY;
@@ -3376,9 +3376,9 @@ int smb2_open(struct ksmbd_work *work)
         * after daccess, saccess, attrib_only, and stream are
         * initialized.
         */
-       write_lock(&fp->f_ci->m_lock);
+       down_write(&fp->f_ci->m_lock);
        list_add(&fp->node, &fp->f_ci->m_fp_list);
-       write_unlock(&fp->f_ci->m_lock);
+       up_write(&fp->f_ci->m_lock);
 
        /* Check delete pending among previous fp before oplock break */
        if (ksmbd_inode_pending_delete(fp)) {
index bd1d2a0e9203a4b5cb5f6509f738b736e578d91c..643f5e1cfe3570ef9f9eae4ca7c3bb7cfd6adbd5 100644 (file)
@@ -64,7 +64,7 @@ struct preauth_integrity_info {
 #define SMB2_SESSION_TIMEOUT           (10 * HZ)
 
 struct create_durable_req_v2 {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le32 Timeout;
        __le32 Flags;
@@ -73,7 +73,7 @@ struct create_durable_req_v2 {
 } __packed;
 
 struct create_durable_reconn_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        union {
                __u8  Reserved[16];
@@ -85,7 +85,7 @@ struct create_durable_reconn_req {
 } __packed;
 
 struct create_durable_reconn_v2_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct {
                __u64 PersistentFileId;
@@ -96,13 +96,13 @@ struct create_durable_reconn_v2_req {
 } __packed;
 
 struct create_alloc_size_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le64 AllocationSize;
 } __packed;
 
 struct create_durable_rsp {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        union {
                __u8  Reserved[8];
@@ -114,7 +114,7 @@ struct create_durable_rsp {
 /* Flags */
 #define SMB2_DHANDLE_FLAG_PERSISTENT   0x00000002
 struct create_durable_v2_rsp {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        __le32 Timeout;
        __le32 Flags;
@@ -122,7 +122,7 @@ struct create_durable_v2_rsp {
 
 /* equivalent of the contents of SMB3.1.1 POSIX open context response */
 struct create_posix_rsp {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8    Name[16];
        __le32 nlink;
        __le32 reparse_tag;
@@ -381,13 +381,13 @@ struct smb2_ea_info {
 } __packed; /* level 15 Query */
 
 struct create_ea_buf_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct smb2_ea_info ea;
 } __packed;
 
 struct create_sd_buf_req {
-       struct create_context ccontext;
+       struct create_context_hdr ccontext;
        __u8   Name[8];
        struct smb_ntsd ntsd;
 } __packed;
index fcaf373cc008044c52bcc9414e53f50af1b98569..474dadf6b7b8bc51b3bfa94c6d29f02621f21cd5 100644 (file)
@@ -646,7 +646,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
         * Lookup fp in master fp list, and check desired access and
         * shared mode between previous open and current open.
         */
-       read_lock(&curr_fp->f_ci->m_lock);
+       down_read(&curr_fp->f_ci->m_lock);
        list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) {
                if (file_inode(filp) != file_inode(prev_fp->filp))
                        continue;
@@ -722,7 +722,7 @@ int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
                        break;
                }
        }
-       read_unlock(&curr_fp->f_ci->m_lock);
+       up_read(&curr_fp->f_ci->m_lock);
 
        return rc;
 }
index 002a3f0dc7c5880b61045cf7f10f7e078b85d6a9..6633fa78e9b96bbbcd323aced36dadc35c19850b 100644 (file)
@@ -448,6 +448,10 @@ static int create_socket(struct interface *iface)
                sin6.sin6_family = PF_INET6;
                sin6.sin6_addr = in6addr_any;
                sin6.sin6_port = htons(server_conf.tcp_port);
+
+               lock_sock(ksmbd_socket->sk);
+               ksmbd_socket->sk->sk_ipv6only = false;
+               release_sock(ksmbd_socket->sk);
        }
 
        ksmbd_tcp_nodelay(ksmbd_socket);
index 030f70700036c17b65f8f16f595ad605e32f8721..6cb599cd287ee44153a8278d40fbcbd8d2f49cb7 100644 (file)
@@ -165,7 +165,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
        ci->m_fattr = 0;
        INIT_LIST_HEAD(&ci->m_fp_list);
        INIT_LIST_HEAD(&ci->m_op_list);
-       rwlock_init(&ci->m_lock);
+       init_rwsem(&ci->m_lock);
        ci->m_de = fp->filp->f_path.dentry;
        return 0;
 }
@@ -261,14 +261,14 @@ static void __ksmbd_inode_close(struct ksmbd_file *fp)
        }
 
        if (atomic_dec_and_test(&ci->m_count)) {
-               write_lock(&ci->m_lock);
+               down_write(&ci->m_lock);
                if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
                        ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
-                       write_unlock(&ci->m_lock);
+                       up_write(&ci->m_lock);
                        ksmbd_vfs_unlink(filp);
-                       write_lock(&ci->m_lock);
+                       down_write(&ci->m_lock);
                }
-               write_unlock(&ci->m_lock);
+               up_write(&ci->m_lock);
 
                ksmbd_inode_free(ci);
        }
@@ -289,9 +289,9 @@ static void __ksmbd_remove_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp
        if (!has_file_id(fp->volatile_id))
                return;
 
-       write_lock(&fp->f_ci->m_lock);
+       down_write(&fp->f_ci->m_lock);
        list_del_init(&fp->node);
-       write_unlock(&fp->f_ci->m_lock);
+       up_write(&fp->f_ci->m_lock);
 
        write_lock(&ft->lock);
        idr_remove(ft->idr, fp->volatile_id);
@@ -523,17 +523,17 @@ struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry)
        if (!ci)
                return NULL;
 
-       read_lock(&ci->m_lock);
+       down_read(&ci->m_lock);
        list_for_each_entry(lfp, &ci->m_fp_list, node) {
                if (inode == file_inode(lfp->filp)) {
                        atomic_dec(&ci->m_count);
                        lfp = ksmbd_fp_get(lfp);
-                       read_unlock(&ci->m_lock);
+                       up_read(&ci->m_lock);
                        return lfp;
                }
        }
        atomic_dec(&ci->m_count);
-       read_unlock(&ci->m_lock);
+       up_read(&ci->m_lock);
        return NULL;
 }
 
@@ -705,13 +705,13 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
 
        conn = fp->conn;
        ci = fp->f_ci;
-       write_lock(&ci->m_lock);
+       down_write(&ci->m_lock);
        list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
                if (op->conn != conn)
                        continue;
                op->conn = NULL;
        }
-       write_unlock(&ci->m_lock);
+       up_write(&ci->m_lock);
 
        fp->conn = NULL;
        fp->tcon = NULL;
@@ -801,13 +801,13 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
        fp->tcon = work->tcon;
 
        ci = fp->f_ci;
-       write_lock(&ci->m_lock);
+       down_write(&ci->m_lock);
        list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
                if (op->conn)
                        continue;
                op->conn = fp->conn;
        }
-       write_unlock(&ci->m_lock);
+       up_write(&ci->m_lock);
 
        __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
        if (!has_file_id(fp->volatile_id)) {
index ed44fb4e18e79c1b87367bfe234767ca99925083..5a225e7055f191b65bf9d6e63017f08fd1144ea5 100644 (file)
@@ -47,7 +47,7 @@ struct stream {
 };
 
 struct ksmbd_inode {
-       rwlock_t                        m_lock;
+       struct rw_semaphore             m_lock;
        atomic_t                        m_count;
        atomic_t                        op_count;
        /* opinfo count for streams */
index 77cdc69eb4220b7764c4e551bf3a350debcec7f6..70bd3e888cfa301be28acf5f6fa5a5b655549d2a 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -658,6 +658,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer)
        tmp.stx_mnt_id = stat->mnt_id;
        tmp.stx_dio_mem_align = stat->dio_mem_align;
        tmp.stx_dio_offset_align = stat->dio_offset_align;
+       tmp.stx_subvol = stat->subvol;
 
        return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
index e9c96a0c79f113f8c49f09bd7c8ea90c2f2677a3..4bf2f8bfec112e32c606540ba7e236575ebc26d0 100644 (file)
@@ -262,17 +262,18 @@ static __poll_t timerfd_poll(struct file *file, poll_table *wait)
        return events;
 }
 
-static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
-                           loff_t *ppos)
+static ssize_t timerfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
+       struct file *file = iocb->ki_filp;
        struct timerfd_ctx *ctx = file->private_data;
        ssize_t res;
        u64 ticks = 0;
 
-       if (count < sizeof(ticks))
+       if (iov_iter_count(to) < sizeof(ticks))
                return -EINVAL;
+
        spin_lock_irq(&ctx->wqh.lock);
-       if (file->f_flags & O_NONBLOCK)
+       if (file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT)
                res = -EAGAIN;
        else
                res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks);
@@ -312,8 +313,11 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
                ctx->ticks = 0;
        }
        spin_unlock_irq(&ctx->wqh.lock);
-       if (ticks)
-               res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);
+       if (ticks) {
+               res = copy_to_iter(&ticks, sizeof(ticks), to);
+               if (!res)
+                       res = -EFAULT;
+       }
        return res;
 }
 
@@ -384,7 +388,7 @@ static long timerfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg
 static const struct file_operations timerfd_fops = {
        .release        = timerfd_release,
        .poll           = timerfd_poll,
-       .read           = timerfd_read,
+       .read_iter      = timerfd_read_iter,
        .llseek         = noop_llseek,
        .show_fdinfo    = timerfd_show,
        .unlocked_ioctl = timerfd_ioctl,
@@ -407,6 +411,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 {
        int ufd;
        struct timerfd_ctx *ctx;
+       struct file *file;
 
        /* Check the TFD_* constants for consistency.  */
        BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
@@ -443,11 +448,22 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
 
        ctx->moffs = ktime_mono_to_real(0);
 
-       ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
-                              O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
-       if (ufd < 0)
+       ufd = get_unused_fd_flags(flags & TFD_SHARED_FCNTL_FLAGS);
+       if (ufd < 0) {
+               kfree(ctx);
+               return ufd;
+       }
+
+       file = anon_inode_getfile("[timerfd]", &timerfd_fops, ctx,
+                                   O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
+       if (IS_ERR(file)) {
+               put_unused_fd(ufd);
                kfree(ctx);
+               return PTR_ERR(file);
+       }
 
+       file->f_mode |= FMODE_NOWAIT;
+       fd_install(ufd, file);
        return ufd;
 }
 
index 894c6ca1e5002015b378ad8d6ec598de44c25ebe..a878cea70f4c9077612e0eefea159746e729fe5c 100644 (file)
@@ -37,6 +37,7 @@ static DEFINE_MUTEX(eventfs_mutex);
 
 struct eventfs_root_inode {
        struct eventfs_inode            ei;
+       struct inode                    *parent_inode;
        struct dentry                   *events_dir;
 };
 
@@ -68,11 +69,25 @@ enum {
        EVENTFS_SAVE_MODE       = BIT(16),
        EVENTFS_SAVE_UID        = BIT(17),
        EVENTFS_SAVE_GID        = BIT(18),
-       EVENTFS_TOPLEVEL        = BIT(19),
 };
 
 #define EVENTFS_MODE_MASK      (EVENTFS_SAVE_MODE - 1)
 
+static void free_ei_rcu(struct rcu_head *rcu)
+{
+       struct eventfs_inode *ei = container_of(rcu, struct eventfs_inode, rcu);
+       struct eventfs_root_inode *rei;
+
+       kfree(ei->entry_attrs);
+       kfree_const(ei->name);
+       if (ei->is_events) {
+               rei = get_root_inode(ei);
+               kfree(rei);
+       } else {
+               kfree(ei);
+       }
+}
+
 /*
  * eventfs_inode reference count management.
  *
@@ -84,18 +99,17 @@ enum {
 static void release_ei(struct kref *ref)
 {
        struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);
-       struct eventfs_root_inode *rei;
+       const struct eventfs_entry *entry;
 
        WARN_ON_ONCE(!ei->is_freed);
 
-       kfree(ei->entry_attrs);
-       kfree_const(ei->name);
-       if (ei->is_events) {
-               rei = get_root_inode(ei);
-               kfree_rcu(rei, ei.rcu);
-       } else {
-               kfree_rcu(ei, rcu);
+       for (int i = 0; i < ei->nr_entries; i++) {
+               entry = &ei->entries[i];
+               if (entry->release)
+                       entry->release(entry->name, ei->data);
        }
+
+       call_rcu(&ei->rcu, free_ei_rcu);
 }
 
 static inline void put_ei(struct eventfs_inode *ei)
@@ -112,6 +126,18 @@ static inline void free_ei(struct eventfs_inode *ei)
        }
 }
 
+/*
+ * Called when creation of an ei fails, do not call release() functions.
+ */
+static inline void cleanup_ei(struct eventfs_inode *ei)
+{
+       if (ei) {
+               /* Set nr_entries to 0 to prevent release() function being called */
+               ei->nr_entries = 0;
+               free_ei(ei);
+       }
+}
+
 static inline struct eventfs_inode *get_ei(struct eventfs_inode *ei)
 {
        if (ei)
@@ -181,21 +207,7 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
         * determined by the parent directory.
         */
        if (dentry->d_inode->i_mode & S_IFDIR) {
-               /*
-                * The events directory dentry is never freed, unless its
-                * part of an instance that is deleted. It's attr is the
-                * default for its child files and directories.
-                * Do not update it. It's not used for its own mode or ownership.
-                */
-               if (ei->is_events) {
-                       /* But it still needs to know if it was modified */
-                       if (iattr->ia_valid & ATTR_UID)
-                               ei->attr.mode |= EVENTFS_SAVE_UID;
-                       if (iattr->ia_valid & ATTR_GID)
-                               ei->attr.mode |= EVENTFS_SAVE_GID;
-               } else {
-                       update_attr(&ei->attr, iattr);
-               }
+               update_attr(&ei->attr, iattr);
 
        } else {
                name = dentry->d_name.name;
@@ -213,18 +225,25 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,
        return ret;
 }
 
-static void update_top_events_attr(struct eventfs_inode *ei, struct super_block *sb)
+static void update_events_attr(struct eventfs_inode *ei, struct super_block *sb)
 {
-       struct inode *root;
+       struct eventfs_root_inode *rei;
+       struct inode *parent;
 
-       /* Only update if the "events" was on the top level */
-       if (!ei || !(ei->attr.mode & EVENTFS_TOPLEVEL))
-               return;
+       rei = get_root_inode(ei);
 
-       /* Get the tracefs root inode. */
-       root = d_inode(sb->s_root);
-       ei->attr.uid = root->i_uid;
-       ei->attr.gid = root->i_gid;
+       /* Use the parent inode permissions unless root set its permissions */
+       parent = rei->parent_inode;
+
+       if (rei->ei.attr.mode & EVENTFS_SAVE_UID)
+               ei->attr.uid = rei->ei.attr.uid;
+       else
+               ei->attr.uid = parent->i_uid;
+
+       if (rei->ei.attr.mode & EVENTFS_SAVE_GID)
+               ei->attr.gid = rei->ei.attr.gid;
+       else
+               ei->attr.gid = parent->i_gid;
 }
 
 static void set_top_events_ownership(struct inode *inode)
@@ -233,10 +252,10 @@ static void set_top_events_ownership(struct inode *inode)
        struct eventfs_inode *ei = ti->private;
 
        /* The top events directory doesn't get automatically updated */
-       if (!ei || !ei->is_events || !(ei->attr.mode & EVENTFS_TOPLEVEL))
+       if (!ei || !ei->is_events)
                return;
 
-       update_top_events_attr(ei, inode->i_sb);
+       update_events_attr(ei, inode->i_sb);
 
        if (!(ei->attr.mode & EVENTFS_SAVE_UID))
                inode->i_uid = ei->attr.uid;
@@ -265,7 +284,7 @@ static int eventfs_permission(struct mnt_idmap *idmap,
        return generic_permission(idmap, inode, mask);
 }
 
-static const struct inode_operations eventfs_root_dir_inode_operations = {
+static const struct inode_operations eventfs_dir_inode_operations = {
        .lookup         = eventfs_root_lookup,
        .setattr        = eventfs_set_attr,
        .getattr        = eventfs_get_attr,
@@ -282,6 +301,35 @@ static const struct file_operations eventfs_file_operations = {
        .llseek         = generic_file_llseek,
 };
 
+/*
+ * On a remount of tracefs, if UID or GID options are set, then
+ * the mount point inode permissions should be used.
+ * Reset the saved permission flags appropriately.
+ */
+void eventfs_remount(struct tracefs_inode *ti, bool update_uid, bool update_gid)
+{
+       struct eventfs_inode *ei = ti->private;
+
+       if (!ei)
+               return;
+
+       if (update_uid)
+               ei->attr.mode &= ~EVENTFS_SAVE_UID;
+
+       if (update_gid)
+               ei->attr.mode &= ~EVENTFS_SAVE_GID;
+
+       if (!ei->entry_attrs)
+               return;
+
+       for (int i = 0; i < ei->nr_entries; i++) {
+               if (update_uid)
+                       ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_UID;
+               if (update_gid)
+                       ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_GID;
+       }
+}
+
 /* Return the evenfs_inode of the "events" directory */
 static struct eventfs_inode *eventfs_find_events(struct dentry *dentry)
 {
@@ -304,7 +352,7 @@ static struct eventfs_inode *eventfs_find_events(struct dentry *dentry)
                // Walk upwards until you find the events inode
        } while (!ei->is_events);
 
-       update_top_events_attr(ei, dentry->d_sb);
+       update_events_attr(ei, dentry->d_sb);
 
        return ei;
 }
@@ -410,7 +458,7 @@ static struct dentry *lookup_dir_entry(struct dentry *dentry,
        update_inode_attr(dentry, inode, &ei->attr,
                          S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
 
-       inode->i_op = &eventfs_root_dir_inode_operations;
+       inode->i_op = &eventfs_dir_inode_operations;
        inode->i_fop = &eventfs_file_operations;
 
        /* All directories will have the same inode number */
@@ -734,7 +782,7 @@ struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode
 
        /* Was the parent freed? */
        if (list_empty(&ei->list)) {
-               free_ei(ei);
+               cleanup_ei(ei);
                ei = NULL;
        }
        return ei;
@@ -781,6 +829,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
        // Note: we have a ref to the dentry from tracefs_start_creating()
        rei = get_root_inode(ei);
        rei->events_dir = dentry;
+       rei->parent_inode = d_inode(dentry->d_sb->s_root);
 
        ei->entries = entries;
        ei->nr_entries = size;
@@ -790,29 +839,26 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
        uid = d_inode(dentry->d_parent)->i_uid;
        gid = d_inode(dentry->d_parent)->i_gid;
 
-       /*
-        * If the events directory is of the top instance, then parent
-        * is NULL. Set the attr.mode to reflect this and its permissions will
-        * default to the tracefs root dentry.
-        */
-       if (!parent)
-               ei->attr.mode = EVENTFS_TOPLEVEL;
-
-       /* This is used as the default ownership of the files and directories */
        ei->attr.uid = uid;
        ei->attr.gid = gid;
 
+       /*
+        * When the "events" directory is created, it takes on the
+        * permissions of its parent. But can be reset on remount.
+        */
+       ei->attr.mode |= EVENTFS_SAVE_UID | EVENTFS_SAVE_GID;
+
        INIT_LIST_HEAD(&ei->children);
        INIT_LIST_HEAD(&ei->list);
 
        ti = get_tracefs(inode);
-       ti->flags |= TRACEFS_EVENT_INODE | TRACEFS_EVENT_TOP_INODE;
+       ti->flags |= TRACEFS_EVENT_INODE;
        ti->private = ei;
 
        inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
        inode->i_uid = uid;
        inode->i_gid = gid;
-       inode->i_op = &eventfs_root_dir_inode_operations;
+       inode->i_op = &eventfs_dir_inode_operations;
        inode->i_fop = &eventfs_file_operations;
 
        dentry->d_fsdata = get_ei(ei);
@@ -835,7 +881,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry
        return ei;
 
  fail:
-       free_ei(ei);
+       cleanup_ei(ei);
        tracefs_failed_creating(dentry);
        return ERR_PTR(-ENOMEM);
 }
index 5545e6bf7d26c4300b70802f40d1f796263624df..a827f6a716c44ec840357a3afee7a51c04296c86 100644 (file)
 
 #include <linux/module.h>
 #include <linux/fs.h>
-#include <linux/mount.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 #include <linux/kobject.h>
 #include <linux/namei.h>
 #include <linux/tracefs.h>
 #include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/seq_file.h>
-#include <linux/parser.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
 #include "internal.h"
@@ -30,20 +30,47 @@ static struct vfsmount *tracefs_mount;
 static int tracefs_mount_count;
 static bool tracefs_registered;
 
+/*
+ * Keep track of all tracefs_inodes in order to update their
+ * flags if necessary on a remount.
+ */
+static DEFINE_SPINLOCK(tracefs_inode_lock);
+static LIST_HEAD(tracefs_inodes);
+
 static struct inode *tracefs_alloc_inode(struct super_block *sb)
 {
        struct tracefs_inode *ti;
+       unsigned long flags;
 
        ti = kmem_cache_alloc(tracefs_inode_cachep, GFP_KERNEL);
        if (!ti)
                return NULL;
 
+       spin_lock_irqsave(&tracefs_inode_lock, flags);
+       list_add_rcu(&ti->list, &tracefs_inodes);
+       spin_unlock_irqrestore(&tracefs_inode_lock, flags);
+
        return &ti->vfs_inode;
 }
 
+static void tracefs_free_inode_rcu(struct rcu_head *rcu)
+{
+       struct tracefs_inode *ti;
+
+       ti = container_of(rcu, struct tracefs_inode, rcu);
+       kmem_cache_free(tracefs_inode_cachep, ti);
+}
+
 static void tracefs_free_inode(struct inode *inode)
 {
-       kmem_cache_free(tracefs_inode_cachep, get_tracefs(inode));
+       struct tracefs_inode *ti = get_tracefs(inode);
+       unsigned long flags;
+
+       spin_lock_irqsave(&tracefs_inode_lock, flags);
+       list_del_rcu(&ti->list);
+       spin_unlock_irqrestore(&tracefs_inode_lock, flags);
+
+       call_rcu(&ti->rcu, tracefs_free_inode_rcu);
 }
 
 static ssize_t default_read_file(struct file *file, char __user *buf,
@@ -153,16 +180,39 @@ static void set_tracefs_inode_owner(struct inode *inode)
 {
        struct tracefs_inode *ti = get_tracefs(inode);
        struct inode *root_inode = ti->private;
+       kuid_t uid;
+       kgid_t gid;
+
+       uid = root_inode->i_uid;
+       gid = root_inode->i_gid;
+
+       /*
+        * If the root is not the mount point, then check the root's
+        * permissions. If it was never set, then default to the
+        * mount point.
+        */
+       if (root_inode != d_inode(root_inode->i_sb->s_root)) {
+               struct tracefs_inode *rti;
+
+               rti = get_tracefs(root_inode);
+               root_inode = d_inode(root_inode->i_sb->s_root);
+
+               if (!(rti->flags & TRACEFS_UID_PERM_SET))
+                       uid = root_inode->i_uid;
+
+               if (!(rti->flags & TRACEFS_GID_PERM_SET))
+                       gid = root_inode->i_gid;
+       }
 
        /*
         * If this inode has never been referenced, then update
         * the permissions to the superblock.
         */
        if (!(ti->flags & TRACEFS_UID_PERM_SET))
-               inode->i_uid = root_inode->i_uid;
+               inode->i_uid = uid;
 
        if (!(ti->flags & TRACEFS_GID_PERM_SET))
-               inode->i_gid = root_inode->i_gid;
+               inode->i_gid = gid;
 }
 
 static int tracefs_permission(struct mnt_idmap *idmap,
@@ -231,7 +281,7 @@ struct inode *tracefs_get_inode(struct super_block *sb)
        return inode;
 }
 
-struct tracefs_mount_opts {
+struct tracefs_fs_info {
        kuid_t uid;
        kgid_t gid;
        umode_t mode;
@@ -243,68 +293,51 @@ enum {
        Opt_uid,
        Opt_gid,
        Opt_mode,
-       Opt_err
 };
 
-static const match_table_t tokens = {
-       {Opt_uid, "uid=%u"},
-       {Opt_gid, "gid=%u"},
-       {Opt_mode, "mode=%o"},
-       {Opt_err, NULL}
+static const struct fs_parameter_spec tracefs_param_specs[] = {
+       fsparam_u32     ("gid",         Opt_gid),
+       fsparam_u32oct  ("mode",        Opt_mode),
+       fsparam_u32     ("uid",         Opt_uid),
+       {}
 };
 
-struct tracefs_fs_info {
-       struct tracefs_mount_opts mount_opts;
-};
-
-static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts)
+static int tracefs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
-       substring_t args[MAX_OPT_ARGS];
-       int option;
-       int token;
+       struct tracefs_fs_info *opts = fc->s_fs_info;
+       struct fs_parse_result result;
        kuid_t uid;
        kgid_t gid;
-       char *p;
-
-       opts->opts = 0;
-       opts->mode = TRACEFS_DEFAULT_MODE;
-
-       while ((p = strsep(&data, ",")) != NULL) {
-               if (!*p)
-                       continue;
-
-               token = match_token(p, tokens, args);
-               switch (token) {
-               case Opt_uid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       uid = make_kuid(current_user_ns(), option);
-                       if (!uid_valid(uid))
-                               return -EINVAL;
-                       opts->uid = uid;
-                       break;
-               case Opt_gid:
-                       if (match_int(&args[0], &option))
-                               return -EINVAL;
-                       gid = make_kgid(current_user_ns(), option);
-                       if (!gid_valid(gid))
-                               return -EINVAL;
-                       opts->gid = gid;
-                       break;
-               case Opt_mode:
-                       if (match_octal(&args[0], &option))
-                               return -EINVAL;
-                       opts->mode = option & S_IALLUGO;
-                       break;
-               /*
-                * We might like to report bad mount options here;
-                * but traditionally tracefs has ignored all mount options
-                */
-               }
-
-               opts->opts |= BIT(token);
+       int opt;
+
+       opt = fs_parse(fc, tracefs_param_specs, param, &result);
+       if (opt < 0)
+               return opt;
+
+       switch (opt) {
+       case Opt_uid:
+               uid = make_kuid(current_user_ns(), result.uint_32);
+               if (!uid_valid(uid))
+                       return invalf(fc, "Unknown uid");
+               opts->uid = uid;
+               break;
+       case Opt_gid:
+               gid = make_kgid(current_user_ns(), result.uint_32);
+               if (!gid_valid(gid))
+                       return invalf(fc, "Unknown gid");
+               opts->gid = gid;
+               break;
+       case Opt_mode:
+               opts->mode = result.uint_32 & S_IALLUGO;
+               break;
+       /*
+        * We might like to report bad mount options here;
+        * but traditionally tracefs has ignored all mount options
+        */
        }
 
+       opts->opts |= BIT(opt);
+
        return 0;
 }
 
@@ -312,7 +345,8 @@ static int tracefs_apply_options(struct super_block *sb, bool remount)
 {
        struct tracefs_fs_info *fsi = sb->s_fs_info;
        struct inode *inode = d_inode(sb->s_root);
-       struct tracefs_mount_opts *opts = &fsi->mount_opts;
+       struct tracefs_inode *ti;
+       bool update_uid, update_gid;
        umode_t tmp_mode;
 
        /*
@@ -320,50 +354,65 @@ static int tracefs_apply_options(struct super_block *sb, bool remount)
         * options.
         */
 
-       if (!remount || opts->opts & BIT(Opt_mode)) {
+       if (!remount || fsi->opts & BIT(Opt_mode)) {
                tmp_mode = READ_ONCE(inode->i_mode) & ~S_IALLUGO;
-               tmp_mode |= opts->mode;
+               tmp_mode |= fsi->mode;
                WRITE_ONCE(inode->i_mode, tmp_mode);
        }
 
-       if (!remount || opts->opts & BIT(Opt_uid))
-               inode->i_uid = opts->uid;
+       if (!remount || fsi->opts & BIT(Opt_uid))
+               inode->i_uid = fsi->uid;
+
+       if (!remount || fsi->opts & BIT(Opt_gid))
+               inode->i_gid = fsi->gid;
+
+       if (remount && (fsi->opts & BIT(Opt_uid) || fsi->opts & BIT(Opt_gid))) {
 
-       if (!remount || opts->opts & BIT(Opt_gid))
-               inode->i_gid = opts->gid;
+               update_uid = fsi->opts & BIT(Opt_uid);
+               update_gid = fsi->opts & BIT(Opt_gid);
+
+               rcu_read_lock();
+               list_for_each_entry_rcu(ti, &tracefs_inodes, list) {
+                       if (update_uid)
+                               ti->flags &= ~TRACEFS_UID_PERM_SET;
+
+                       if (update_gid)
+                               ti->flags &= ~TRACEFS_GID_PERM_SET;
+
+                       if (ti->flags & TRACEFS_EVENT_INODE)
+                               eventfs_remount(ti, update_uid, update_gid);
+               }
+               rcu_read_unlock();
+       }
 
        return 0;
 }
 
-static int tracefs_remount(struct super_block *sb, int *flags, char *data)
+static int tracefs_reconfigure(struct fs_context *fc)
 {
-       int err;
-       struct tracefs_fs_info *fsi = sb->s_fs_info;
+       struct super_block *sb = fc->root->d_sb;
+       struct tracefs_fs_info *sb_opts = sb->s_fs_info;
+       struct tracefs_fs_info *new_opts = fc->s_fs_info;
 
        sync_filesystem(sb);
-       err = tracefs_parse_options(data, &fsi->mount_opts);
-       if (err)
-               goto fail;
-
-       tracefs_apply_options(sb, true);
+       /* structure copy of new mount options to sb */
+       *sb_opts = *new_opts;
 
-fail:
-       return err;
+       return tracefs_apply_options(sb, true);
 }
 
 static int tracefs_show_options(struct seq_file *m, struct dentry *root)
 {
        struct tracefs_fs_info *fsi = root->d_sb->s_fs_info;
-       struct tracefs_mount_opts *opts = &fsi->mount_opts;
 
-       if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
+       if (!uid_eq(fsi->uid, GLOBAL_ROOT_UID))
                seq_printf(m, ",uid=%u",
-                          from_kuid_munged(&init_user_ns, opts->uid));
-       if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
+                          from_kuid_munged(&init_user_ns, fsi->uid));
+       if (!gid_eq(fsi->gid, GLOBAL_ROOT_GID))
                seq_printf(m, ",gid=%u",
-                          from_kgid_munged(&init_user_ns, opts->gid));
-       if (opts->mode != TRACEFS_DEFAULT_MODE)
-               seq_printf(m, ",mode=%o", opts->mode);
+                          from_kgid_munged(&init_user_ns, fsi->gid));
+       if (fsi->mode != TRACEFS_DEFAULT_MODE)
+               seq_printf(m, ",mode=%o", fsi->mode);
 
        return 0;
 }
@@ -373,7 +422,6 @@ static const struct super_operations tracefs_super_operations = {
        .free_inode     = tracefs_free_inode,
        .drop_inode     = generic_delete_inode,
        .statfs         = simple_statfs,
-       .remount_fs     = tracefs_remount,
        .show_options   = tracefs_show_options,
 };
 
@@ -398,31 +446,34 @@ static int tracefs_d_revalidate(struct dentry *dentry, unsigned int flags)
        return !(ei && ei->is_freed);
 }
 
+static void tracefs_d_iput(struct dentry *dentry, struct inode *inode)
+{
+       struct tracefs_inode *ti = get_tracefs(inode);
+
+       /*
+        * This inode is being freed and cannot be used for
+        * eventfs. Clear the flag so that it doesn't call into
+        * eventfs during the remount flag updates. The eventfs_inode
+        * gets freed after an RCU cycle, so the content will still
+        * be safe if the iteration is going on now.
+        */
+       ti->flags &= ~TRACEFS_EVENT_INODE;
+}
+
 static const struct dentry_operations tracefs_dentry_operations = {
+       .d_iput = tracefs_d_iput,
        .d_revalidate = tracefs_d_revalidate,
        .d_release = tracefs_d_release,
 };
 
-static int trace_fill_super(struct super_block *sb, void *data, int silent)
+static int tracefs_fill_super(struct super_block *sb, struct fs_context *fc)
 {
        static const struct tree_descr trace_files[] = {{""}};
-       struct tracefs_fs_info *fsi;
        int err;
 
-       fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL);
-       sb->s_fs_info = fsi;
-       if (!fsi) {
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       err = tracefs_parse_options(data, &fsi->mount_opts);
+       err = simple_fill_super(sb, TRACEFS_MAGIC, trace_files);
        if (err)
-               goto fail;
-
-       err  =  simple_fill_super(sb, TRACEFS_MAGIC, trace_files);
-       if (err)
-               goto fail;
+               return err;
 
        sb->s_op = &tracefs_super_operations;
        sb->s_d_op = &tracefs_dentry_operations;
@@ -430,24 +481,45 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)
        tracefs_apply_options(sb, false);
 
        return 0;
+}
 
-fail:
-       kfree(fsi);
-       sb->s_fs_info = NULL;
-       return err;
+static int tracefs_get_tree(struct fs_context *fc)
+{
+       return get_tree_single(fc, tracefs_fill_super);
+}
+
+static void tracefs_free_fc(struct fs_context *fc)
+{
+       kfree(fc->s_fs_info);
 }
 
-static struct dentry *trace_mount(struct file_system_type *fs_type,
-                       int flags, const char *dev_name,
-                       void *data)
+static const struct fs_context_operations tracefs_context_ops = {
+       .free           = tracefs_free_fc,
+       .parse_param    = tracefs_parse_param,
+       .get_tree       = tracefs_get_tree,
+       .reconfigure    = tracefs_reconfigure,
+};
+
+static int tracefs_init_fs_context(struct fs_context *fc)
 {
-       return mount_single(fs_type, flags, data, trace_fill_super);
+       struct tracefs_fs_info *fsi;
+
+       fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL);
+       if (!fsi)
+               return -ENOMEM;
+
+       fsi->mode = TRACEFS_DEFAULT_MODE;
+
+       fc->s_fs_info = fsi;
+       fc->ops = &tracefs_context_ops;
+       return 0;
 }
 
 static struct file_system_type trace_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "tracefs",
-       .mount =        trace_mount,
+       .init_fs_context = tracefs_init_fs_context,
+       .parameters     = tracefs_param_specs,
        .kill_sb =      kill_litter_super,
 };
 MODULE_ALIAS_FS("tracefs");
index 15c26f9aaad4df1fe3d509061ba6cd3b437ae76e..f704d8348357ed8f8a2a11195718b716e7277244 100644 (file)
@@ -4,15 +4,18 @@
 
 enum {
        TRACEFS_EVENT_INODE             = BIT(1),
-       TRACEFS_EVENT_TOP_INODE         = BIT(2),
-       TRACEFS_GID_PERM_SET            = BIT(3),
-       TRACEFS_UID_PERM_SET            = BIT(4),
-       TRACEFS_INSTANCE_INODE          = BIT(5),
+       TRACEFS_GID_PERM_SET            = BIT(2),
+       TRACEFS_UID_PERM_SET            = BIT(3),
+       TRACEFS_INSTANCE_INODE          = BIT(4),
 };
 
 struct tracefs_inode {
-       struct inode            vfs_inode;
+       union {
+               struct inode            vfs_inode;
+               struct rcu_head         rcu;
+       };
        /* The below gets initialized with memset_after(ti, 0, vfs_inode) */
+       struct list_head        list;
        unsigned long           flags;
        void                    *private;
 };
@@ -73,6 +76,7 @@ struct dentry *tracefs_end_creating(struct dentry *dentry);
 struct dentry *tracefs_failed_creating(struct dentry *dentry);
 struct inode *tracefs_get_inode(struct super_block *sb);
 
+void eventfs_remount(struct tracefs_inode *ti, bool update_uid, bool update_gid);
 void eventfs_d_release(struct dentry *dentry);
 
 #endif /* _TRACEFS_INTERNAL_H */
index 60dcfafdc11a84d0d6ebe74ebc99c90ff145a35a..2a564f813314300896b36fb2d5a48f9ae8eb38b9 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/hugetlb.h>
 #include <linux/swapops.h>
 #include <linux/miscdevice.h>
+#include <linux/uio.h>
 
 static int sysctl_unprivileged_userfaultfd __read_mostly;
 
@@ -282,7 +283,7 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
 /*
  * Verify the pagetables are still not ok after having reigstered into
  * the fault_pending_wqh to avoid userland having to UFFDIO_WAKE any
- * userfault that has already been resolved, if userfaultfd_read and
+ * userfault that has already been resolved, if userfaultfd_read_iter and
  * UFFDIO_COPY|ZEROPAGE are being run simultaneously on two different
  * threads.
  */
@@ -895,6 +896,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
                        prev = vma;
                        continue;
                }
+               /* Reset ptes for the whole vma range if wr-protected */
+               if (userfaultfd_wp(vma))
+                       uffd_wp_range(vma, vma->vm_start,
+                                     vma->vm_end - vma->vm_start, false);
                new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
                vma = vma_modify_flags_uffd(&vmi, prev, vma, vma->vm_start,
                                            vma->vm_end, new_flags,
@@ -1177,34 +1182,34 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
        return ret;
 }
 
-static ssize_t userfaultfd_read(struct file *file, char __user *buf,
-                               size_t count, loff_t *ppos)
+static ssize_t userfaultfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
 {
+       struct file *file = iocb->ki_filp;
        struct userfaultfd_ctx *ctx = file->private_data;
        ssize_t _ret, ret = 0;
        struct uffd_msg msg;
-       int no_wait = file->f_flags & O_NONBLOCK;
        struct inode *inode = file_inode(file);
+       bool no_wait;
 
        if (!userfaultfd_is_initialized(ctx))
                return -EINVAL;
 
+       no_wait = file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT;
        for (;;) {
-               if (count < sizeof(msg))
+               if (iov_iter_count(to) < sizeof(msg))
                        return ret ? ret : -EINVAL;
                _ret = userfaultfd_ctx_read(ctx, no_wait, &msg, inode);
                if (_ret < 0)
                        return ret ? ret : _ret;
-               if (copy_to_user((__u64 __user *) buf, &msg, sizeof(msg)))
+               _ret = !copy_to_iter_full(&msg, sizeof(msg), to);
+               if (_ret)
                        return ret ? ret : -EFAULT;
                ret += sizeof(msg);
-               buf += sizeof(msg);
-               count -= sizeof(msg);
                /*
                 * Allow to read more than one fault at time but only
                 * block if waiting for the very first one.
                 */
-               no_wait = O_NONBLOCK;
+               no_wait = true;
        }
 }
 
@@ -2172,7 +2177,7 @@ static const struct file_operations userfaultfd_fops = {
 #endif
        .release        = userfaultfd_release,
        .poll           = userfaultfd_poll,
-       .read           = userfaultfd_read,
+       .read_iter      = userfaultfd_read_iter,
        .unlocked_ioctl = userfaultfd_ioctl,
        .compat_ioctl   = compat_ptr_ioctl,
        .llseek         = noop_llseek,
@@ -2192,6 +2197,7 @@ static void init_once_userfaultfd_ctx(void *mem)
 static int new_userfaultfd(int flags)
 {
        struct userfaultfd_ctx *ctx;
+       struct file *file;
        int fd;
 
        BUG_ON(!current->mm);
@@ -2215,16 +2221,26 @@ static int new_userfaultfd(int flags)
        init_rwsem(&ctx->map_changing_lock);
        atomic_set(&ctx->mmap_changing, 0);
        ctx->mm = current->mm;
-       /* prevent the mm struct to be freed */
-       mmgrab(ctx->mm);
+
+       fd = get_unused_fd_flags(flags & UFFD_SHARED_FCNTL_FLAGS);
+       if (fd < 0)
+               goto err_out;
 
        /* Create a new inode so that the LSM can block the creation.  */
-       fd = anon_inode_create_getfd("[userfaultfd]", &userfaultfd_fops, ctx,
+       file = anon_inode_create_getfile("[userfaultfd]", &userfaultfd_fops, ctx,
                        O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
-       if (fd < 0) {
-               mmdrop(ctx->mm);
-               kmem_cache_free(userfaultfd_ctx_cachep, ctx);
+       if (IS_ERR(file)) {
+               put_unused_fd(fd);
+               fd = PTR_ERR(file);
+               goto err_out;
        }
+       /* prevent the mm struct to be freed */
+       mmgrab(ctx->mm);
+       file->f_mode |= FMODE_NOWAIT;
+       fd_install(fd, file);
+       return fd;
+err_out:
+       kmem_cache_free(userfaultfd_ctx_cachep, ctx);
        return fd;
 }
 
index 632653e00906fa32e2b5a8c70451522952a8660a..2ce302b4885f53b9e69d21a63f8897e4c7e4b022 100644 (file)
@@ -1230,8 +1230,7 @@ xfs_file_open(
 {
        if (xfs_is_shutdown(XFS_M(inode->i_sb)))
                return -EIO;
-       file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC | FMODE_BUF_WASYNC |
-                       FMODE_DIO_PARALLEL_WRITE | FMODE_CAN_ODIRECT;
+       file->f_mode |= FMODE_NOWAIT | FMODE_CAN_ODIRECT;
        return generic_file_open(inode, file);
 }
 
@@ -1244,7 +1243,9 @@ xfs_dir_open(
        unsigned int    mode;
        int             error;
 
-       error = xfs_file_open(inode, file);
+       if (xfs_is_shutdown(ip->i_mount))
+               return -EIO;
+       error = generic_file_open(inode, file);
        if (error)
                return error;
 
@@ -1490,7 +1491,6 @@ const struct file_operations xfs_file_operations = {
        .compat_ioctl   = xfs_file_compat_ioctl,
 #endif
        .mmap           = xfs_file_mmap,
-       .mmap_supported_flags = MAP_SYNC,
        .open           = xfs_file_open,
        .release        = xfs_file_release,
        .fsync          = xfs_file_fsync,
@@ -1498,6 +1498,8 @@ const struct file_operations xfs_file_operations = {
        .fallocate      = xfs_file_fallocate,
        .fadvise        = xfs_file_fadvise,
        .remap_file_range = xfs_file_remap_range,
+       .fop_flags      = FOP_MMAP_SYNC | FOP_BUFFER_RASYNC |
+                         FOP_BUFFER_WASYNC | FOP_DIO_PARALLEL_WRITE,
 };
 
 const struct file_operations xfs_dir_file_operations = {
index 2090729701ab6d7a0d71861c7bd2cf4fb926b38e..9339da7c20a8b54eed01315e6f126fd96d951b0e 100644 (file)
@@ -87,4 +87,9 @@ void aes_decrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
 extern const u8 crypto_aes_sbox[];
 extern const u8 crypto_aes_inv_sbox[];
 
+void aescfb_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src,
+                   int len, const u8 iv[AES_BLOCK_SIZE]);
+void aescfb_decrypt(const struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src,
+                   int len, const u8 iv[AES_BLOCK_SIZE]);
+
 #endif
index 19ac7b36f608eafdf1b25bbabeea4296ddffe8d3..d040033dc8eea0530cd9ddf530a1f0d67679f6d2 100644 (file)
 #define QCOM_ID_QRU1000                        539
 #define QCOM_ID_SM8475_2               540
 #define QCOM_ID_QDU1000                        545
+#define QCOM_ID_X1E80100               555
 #define QCOM_ID_SM8650                 557
 #define QCOM_ID_SM4450                 568
 #define QCOM_ID_QDU1010                        587
index 3dac3577788a70af3b5c80a0ea5b599559e53c59..442f9e9037dc33198a1cee20af62fc70bbd96605 100644 (file)
 #define CLK_APM_PLL_DIV4_APM                           70
 #define CLK_APM_PLL_DIV16_APM                          71
 
+/* CMU_HSI0 */
+#define CLK_FOUT_USB_PLL                                       1
+#define CLK_MOUT_PLL_USB                                       2
+#define CLK_MOUT_HSI0_ALT_USER                                 3
+#define CLK_MOUT_HSI0_BUS_USER                                 4
+#define CLK_MOUT_HSI0_DPGTC_USER                               5
+#define CLK_MOUT_HSI0_TCXO_USER                                        6
+#define CLK_MOUT_HSI0_USB20_USER                               7
+#define CLK_MOUT_HSI0_USB31DRD_USER                            8
+#define CLK_MOUT_HSI0_USBDPDBG_USER                            9
+#define CLK_MOUT_HSI0_BUS                                      10
+#define CLK_MOUT_HSI0_USB20_REF                                        11
+#define CLK_MOUT_HSI0_USB31DRD                                 12
+#define CLK_DOUT_HSI0_USB31DRD                                 13
+#define CLK_GOUT_HSI0_PCLK                                     14
+#define CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_SUSPEND_CLK_26       15
+#define CLK_GOUT_HSI0_CLK_HSI0_ALT                             16
+#define CLK_GOUT_HSI0_DP_LINK_I_DP_GTC_CLK                     17
+#define CLK_GOUT_HSI0_DP_LINK_I_PCLK                           18
+#define CLK_GOUT_HSI0_D_TZPC_HSI0_PCLK                         19
+#define CLK_GOUT_HSI0_ETR_MIU_I_ACLK                           20
+#define CLK_GOUT_HSI0_ETR_MIU_I_PCLK                           21
+#define CLK_GOUT_HSI0_GPC_HSI0_PCLK                            22
+#define CLK_GOUT_HSI0_LHM_AXI_G_ETR_HSI0_I_CLK                 23
+#define CLK_GOUT_HSI0_LHM_AXI_P_AOCHSI0_I_CLK                  24
+#define CLK_GOUT_HSI0_LHM_AXI_P_HSI0_I_CLK                     25
+#define CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_I_CLK                    26
+#define CLK_GOUT_HSI0_LHS_AXI_D_HSI0AOC_I_CLK                  27
+#define CLK_GOUT_HSI0_PPMU_HSI0_AOC_ACLK                       28
+#define CLK_GOUT_HSI0_PPMU_HSI0_AOC_PCLK                       29
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS0_ACLK                      30
+#define CLK_GOUT_HSI0_PPMU_HSI0_BUS0_PCLK                      31
+#define CLK_GOUT_HSI0_CLK_HSI0_BUS_CLK                         32
+#define CLK_GOUT_HSI0_SSMT_USB_ACLK                            33
+#define CLK_GOUT_HSI0_SSMT_USB_PCLK                            34
+#define CLK_GOUT_HSI0_SYSMMU_USB_CLK_S2                                35
+#define CLK_GOUT_HSI0_SYSREG_HSI0_PCLK                         36
+#define CLK_GOUT_HSI0_UASC_HSI0_CTRL_ACLK                      37
+#define CLK_GOUT_HSI0_UASC_HSI0_CTRL_PCLK                      38
+#define CLK_GOUT_HSI0_UASC_HSI0_LINK_ACLK                      39
+#define CLK_GOUT_HSI0_UASC_HSI0_LINK_PCLK                      40
+#define CLK_GOUT_HSI0_USB31DRD_ACLK_PHYCTRL                    41
+#define CLK_GOUT_HSI0_USB31DRD_BUS_CLK_EARLY                   42
+#define CLK_GOUT_HSI0_USB31DRD_I_USB20_PHY_REFCLK_26           43
+#define CLK_GOUT_HSI0_USB31DRD_I_USB31DRD_REF_CLK_40           44
+#define CLK_GOUT_HSI0_USB31DRD_I_USBDPPHY_REF_SOC_PLL          45
+#define CLK_GOUT_HSI0_USB31DRD_I_USBDPPHY_SCL_APB_PCLK         46
+#define CLK_GOUT_HSI0_USB31DRD_I_USBPCS_APB_CLK                        47
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_I_ACLK                 48
+#define CLK_GOUT_HSI0_USB31DRD_USBDPPHY_UDBG_I_APB_PCLK                49
+#define CLK_GOUT_HSI0_XIU_D0_HSI0_ACLK                         50
+#define CLK_GOUT_HSI0_XIU_D1_HSI0_ACLK                         51
+#define CLK_GOUT_HSI0_XIU_P_HSI0_ACLK                          52
+
+/* CMU_HSI2 */
+#define CLK_MOUT_HSI2_BUS_USER                                         1
+#define CLK_MOUT_HSI2_MMC_CARD_USER                                    2
+#define CLK_MOUT_HSI2_PCIE_USER                                                3
+#define CLK_MOUT_HSI2_UFS_EMBD_USER                                    4
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_003_PHY_REFCLK_IN               5
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_004_PHY_REFCLK_IN               6
+#define CLK_GOUT_HSI2_SSMT_PCIE_IA_GEN4A_1_ACLK                                7
+#define CLK_GOUT_HSI2_SSMT_PCIE_IA_GEN4A_1_PCLK                                8
+#define CLK_GOUT_HSI2_SSMT_PCIE_IA_GEN4B_1_ACLK                                9
+#define CLK_GOUT_HSI2_SSMT_PCIE_IA_GEN4B_1_PCLK                                10
+#define CLK_GOUT_HSI2_D_TZPC_HSI2_PCLK                                 11
+#define CLK_GOUT_HSI2_GPC_HSI2_PCLK                                    12
+#define CLK_GOUT_HSI2_GPIO_HSI2_PCLK                                   13
+#define CLK_GOUT_HSI2_HSI2_CMU_HSI2_PCLK                               14
+#define CLK_GOUT_HSI2_LHM_AXI_P_HSI2_I_CLK                             15
+#define CLK_GOUT_HSI2_LHS_ACEL_D_HSI2_I_CLK                            16
+#define CLK_GOUT_HSI2_MMC_CARD_I_ACLK                                  17
+#define CLK_GOUT_HSI2_MMC_CARD_SDCLKIN                                 18
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_003_DBI_ACLK_UG                 19
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_003_MSTR_ACLK_UG                        20
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_003_SLV_ACLK_UG                 21
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_003_I_DRIVER_APB_CLK            22
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_004_DBI_ACLK_UG                 23
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_004_MSTR_ACLK_UG                        24
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_004_SLV_ACLK_UG                 25
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCIE_004_I_DRIVER_APB_CLK            26
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCS_PMA_PHY_UDBG_I_APB_PCLK          27
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCS_PMA_PIPE_PAL_PCIE_I_APB_PCLK     28
+#define CLK_GOUT_HSI2_PCIE_GEN4_1_PCS_PMA_PCIEPHY210X2_QCH_I_APB_PCLK  29
+#define CLK_GOUT_HSI2_PCIE_IA_GEN4A_1_I_CLK                            30
+#define CLK_GOUT_HSI2_PCIE_IA_GEN4B_1_I_CLK                            31
+#define CLK_GOUT_HSI2_PPMU_HSI2_ACLK                                   32
+#define CLK_GOUT_HSI2_PPMU_HSI2_PCLK                                   33
+#define CLK_GOUT_HSI2_QE_MMC_CARD_HSI2_ACLK                            34
+#define CLK_GOUT_HSI2_QE_MMC_CARD_HSI2_PCLK                            35
+#define CLK_GOUT_HSI2_QE_PCIE_GEN4A_HSI2_ACLK                          36
+#define CLK_GOUT_HSI2_QE_PCIE_GEN4A_HSI2_PCLK                          37
+#define CLK_GOUT_HSI2_QE_PCIE_GEN4B_HSI2_ACLK                          38
+#define CLK_GOUT_HSI2_QE_PCIE_GEN4B_HSI2_PCLK                          39
+#define CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_ACLK                            40
+#define CLK_GOUT_HSI2_QE_UFS_EMBD_HSI2_PCLK                            41
+#define CLK_GOUT_HSI2_CLK_HSI2_BUS_CLK                                 42
+#define CLK_GOUT_HSI2_CLK_HSI2_OSCCLK_CLK                              43
+#define CLK_GOUT_HSI2_SSMT_HSI2_ACLK                                   44
+#define CLK_GOUT_HSI2_SSMT_HSI2_PCLK                                   45
+#define CLK_GOUT_HSI2_SYSMMU_HSI2_CLK_S2                               46
+#define CLK_GOUT_HSI2_SYSREG_HSI2_PCLK                                 47
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4A_DBI_1_ACLK                       48
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4A_DBI_1_PCLK                       49
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4A_SLV_1_ACLK                       50
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4A_SLV_1_PCLK                       51
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4B_DBI_1_ACLK                       52
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4B_DBI_1_PCLK                       53
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4B_SLV_1_ACLK                       54
+#define CLK_GOUT_HSI2_UASC_PCIE_GEN4B_SLV_1_PCLK                       55
+#define CLK_GOUT_HSI2_UFS_EMBD_I_ACLK                                  56
+#define CLK_GOUT_HSI2_UFS_EMBD_I_CLK_UNIPRO                            57
+#define CLK_GOUT_HSI2_UFS_EMBD_I_FMP_CLK                               58
+#define CLK_GOUT_HSI2_XIU_D_HSI2_ACLK                                  59
+#define CLK_GOUT_HSI2_XIU_P_HSI2_ACLK                                  60
+
 /* CMU_MISC */
 #define CLK_MOUT_MISC_BUS_USER                         1
 #define CLK_MOUT_MISC_SSS_USER                         2
index 1ec4827b80916054f353a60787f37f3021587255..655440a3e7c6868a547e0ec7f0ab439829fe522c 100644 (file)
 #define R8A73A4_CLK_ZS         14
 #define R8A73A4_CLK_HP         15
 
+/* MSTP1 */
+#define R8A73A4_CLK_TMU0       25
+#define R8A73A4_CLK_TMU3       21
+
 /* MSTP2 */
 #define R8A73A4_CLK_DMAC       18
 #define R8A73A4_CLK_SCIFB3     17
diff --git a/include/keys/trusted_dcp.h b/include/keys/trusted_dcp.h
new file mode 100644 (file)
index 0000000..9aaa420
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 sigma star gmbh
+ */
+
+#ifndef TRUSTED_DCP_H
+#define TRUSTED_DCP_H
+
+extern struct trusted_key_ops dcp_trusted_key_ops;
+
+#endif
index 7769b726863ab10b5b160366d7fa918784491995..a088b33fd0e3b7d5ed981fcbda082b03c9933461 100644 (file)
@@ -6,8 +6,6 @@
 #include <linux/tpm_command.h>
 
 /* implementation specific TPM constants */
-#define MAX_BUF_SIZE                   1024
-#define TPM_GETRANDOM_SIZE             14
 #define TPM_SIZE_OFFSET                        2
 #define TPM_RETURN_OFFSET              6
 #define TPM_DATA_OFFSET                        10
index 93a5f16d03f3f38612d37f0bcef56e6948912413..edef565c2a1a141409b6c6984a695226f9697bf7 100644 (file)
@@ -9,12 +9,17 @@
 #ifndef _LINUX_ANON_INODES_H
 #define _LINUX_ANON_INODES_H
 
+#include <linux/types.h>
+
 struct file_operations;
 struct inode;
 
 struct file *anon_inode_getfile(const char *name,
                                const struct file_operations *fops,
                                void *priv, int flags);
+struct file *anon_inode_getfile_fmode(const char *name,
+                               const struct file_operations *fops,
+                               void *priv, int flags, fmode_t f_mode);
 struct file *anon_inode_create_getfile(const char *name,
                                       const struct file_operations *fops,
                                       void *priv, int flags,
index c906f666ff5d22007d1732bb0706d891ded27551..c82d56768101395c36763373705c9315d2acb8c6 100644 (file)
 /* FFA Bus/Device/Driver related */
 struct ffa_device {
        u32 id;
+       u32 properties;
        int vm_id;
        bool mode_32bit;
        uuid_t uuid;
@@ -221,12 +222,29 @@ struct ffa_partition_info {
 #define FFA_PARTITION_DIRECT_SEND      BIT(1)
 /* partition can send and receive indirect messages. */
 #define FFA_PARTITION_INDIRECT_MSG     BIT(2)
+/* partition can receive notifications */
+#define FFA_PARTITION_NOTIFICATION_RECV        BIT(3)
 /* partition runs in the AArch64 execution state. */
 #define FFA_PARTITION_AARCH64_EXEC     BIT(8)
        u32 properties;
        u32 uuid[4];
 };
 
+static inline
+bool ffa_partition_check_property(struct ffa_device *dev, u32 property)
+{
+       return dev->properties & property;
+}
+
+#define ffa_partition_supports_notify_recv(dev)        \
+       ffa_partition_check_property(dev, FFA_PARTITION_NOTIFICATION_RECV)
+
+#define ffa_partition_supports_indirect_msg(dev)       \
+       ffa_partition_check_property(dev, FFA_PARTITION_INDIRECT_MSG)
+
+#define ffa_partition_supports_direct_recv(dev)        \
+       ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_RECV)
+
 /* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
 struct ffa_send_direct_data {
        unsigned long data0; /* w3/x3 */
@@ -236,6 +254,14 @@ struct ffa_send_direct_data {
        unsigned long data4; /* w7/x7 */
 };
 
+struct ffa_indirect_msg_hdr {
+       u32 flags;
+       u32 res0;
+       u32 offset;
+       u32 send_recv_id;
+       u32 size;
+};
+
 struct ffa_mem_region_addr_range {
        /* The base IPA of the constituent memory region, aligned to 4 kiB */
        u64 address;
@@ -396,6 +422,7 @@ struct ffa_msg_ops {
        void (*mode_32bit_set)(struct ffa_device *dev);
        int (*sync_send_receive)(struct ffa_device *dev,
                                 struct ffa_send_direct_data *data);
+       int (*indirect_send)(struct ffa_device *dev, void *buf, size_t sz);
 };
 
 struct ffa_mem_ops {
index cb1526ec44b5f66572337fff1ba61dcc704a1d19..c3e098b21c161ecaf0bb13fd2e96fc3e2b4a1d57 100644 (file)
@@ -88,15 +88,9 @@ struct block_device {
 
 /*
  * Block error status values.  See block/blk-core:blk_errors for the details.
- * Alpha cannot write a byte atomically, so we need to use 32-bit value.
  */
-#if defined(CONFIG_ALPHA) && !defined(__alpha_bwx__)
-typedef u32 __bitwise blk_status_t;
-typedef u32 blk_short_t;
-#else
 typedef u8 __bitwise blk_status_t;
 typedef u16 blk_short_t;
-#endif
 #define        BLK_STS_OK 0
 #define BLK_STS_NOTSUPP                ((__force blk_status_t)1)
 #define BLK_STS_TIMEOUT                ((__force blk_status_t)2)
diff --git a/include/linux/bus/stm32_firewall_device.h b/include/linux/bus/stm32_firewall_device.h
new file mode 100644 (file)
index 0000000..18e0a2f
--- /dev/null
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef STM32_FIREWALL_DEVICE_H
+#define STM32_FIREWALL_DEVICE_H
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#define STM32_FIREWALL_MAX_EXTRA_ARGS          5
+
+/* Opaque reference to stm32_firewall_controller */
+struct stm32_firewall_controller;
+
+/**
+ * struct stm32_firewall - Information on a device's firewall. Each device can have more than one
+ *                        firewall.
+ *
+ * @firewall_ctrl:             Pointer referencing a firewall controller of the device. It is
+ *                             opaque so a device cannot manipulate the controller's ops or access
+ *                             the controller's data
+ * @extra_args:                        Extra arguments that are implementation dependent
+ * @entry:                     Name of the firewall entry
+ * @extra_args_size:           Number of extra arguments
+ * @firewall_id:               Firewall ID associated the device for this firewall controller
+ */
+struct stm32_firewall {
+       struct stm32_firewall_controller *firewall_ctrl;
+       u32 extra_args[STM32_FIREWALL_MAX_EXTRA_ARGS];
+       const char *entry;
+       size_t extra_args_size;
+       u32 firewall_id;
+};
+
+#if IS_ENABLED(CONFIG_STM32_FIREWALL)
+/**
+ * stm32_firewall_get_firewall - Get the firewall(s) associated to given device.
+ *                              The firewall controller reference is always the first argument
+ *                              of each of the access-controller property entries.
+ *                              The firewall ID is always the second argument of each of the
+ *                              access-controller  property entries.
+ *                              If there's no argument linked to the phandle, then the firewall ID
+ *                              field is set to U32_MAX, which is an invalid ID.
+ *
+ * @np:                                Device node to parse
+ * @firewall:                  Array of firewall references
+ * @nb_firewall:               Number of firewall references to get. Must be at least 1.
+ *
+ * Returns 0 on success, -ENODEV if there's no match with a firewall controller or appropriate errno
+ * code if error occurred.
+ */
+int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
+                               unsigned int nb_firewall);
+
+/**
+ * stm32_firewall_grant_access - Request firewall access rights and grant access.
+ *
+ * @firewall:                  Firewall reference containing the ID to check against its firewall
+ *                             controller
+ *
+ * Returns 0 if access is granted, -EACCES if access is denied, -ENODEV if firewall is null or
+ * appropriate errno code if error occurred
+ */
+int stm32_firewall_grant_access(struct stm32_firewall *firewall);
+
+/**
+ * stm32_firewall_release_access - Release access granted from a call to
+ *                                stm32_firewall_grant_access().
+ *
+ * @firewall:                  Firewall reference containing the ID to check against its firewall
+ *                             controller
+ */
+void stm32_firewall_release_access(struct stm32_firewall *firewall);
+
+/**
+ * stm32_firewall_grant_access_by_id - Request firewall access rights of a given device
+ *                                    based on a specific firewall ID
+ *
+ * Warnings:
+ * There is no way to ensure that the given ID will correspond to the firewall referenced in the
+ * device node if the ID did not come from stm32_firewall_get_firewall(). In that case, this
+ * function must be used with caution.
+ * This function should be used for subsystem resources that do not have the same firewall ID
+ * as their parent.
+ * U32_MAX is an invalid ID.
+ *
+ * @firewall:                  Firewall reference containing the firewall controller
+ * @subsystem_id:              Firewall ID of the subsystem resource
+ *
+ * Returns 0 if access is granted, -EACCES if access is denied, -ENODEV if firewall is null or
+ * appropriate errno code if error occurred
+ */
+int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id);
+
+/**
+ * stm32_firewall_release_access_by_id - Release access granted from a call to
+ *                                      stm32_firewall_grant_access_by_id().
+ *
+ * Warnings:
+ * There is no way to ensure that the given ID will correspond to the firewall referenced in the
+ * device node if the ID did not come from stm32_firewall_get_firewall(). In that case, this
+ * function must be used with caution.
+ * This function should be used for subsystem resources that do not have the same firewall ID
+ * as their parent.
+ * U32_MAX is an invalid ID.
+ *
+ * @firewall:                  Firewall reference containing the firewall controller
+ * @subsystem_id:              Firewall ID of the subsystem resource
+ */
+void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id);
+
+#else /* CONFIG_STM32_FIREWALL */
+
+int stm32_firewall_get_firewall(struct device_node *np, struct stm32_firewall *firewall,
+                               unsigned int nb_firewall);
+{
+       return -ENODEV;
+}
+
+int stm32_firewall_grant_access(struct stm32_firewall *firewall)
+{
+       return -ENODEV;
+}
+
+void stm32_firewall_release_access(struct stm32_firewall *firewall)
+{
+}
+
+int stm32_firewall_grant_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
+{
+       return -ENODEV;
+}
+
+void stm32_firewall_release_access_by_id(struct stm32_firewall *firewall, u32 subsystem_id)
+{
+}
+
+#endif /* CONFIG_STM32_FIREWALL */
+#endif /* STM32_FIREWALL_DEVICE_H */
diff --git a/include/linux/cmpxchg-emu.h b/include/linux/cmpxchg-emu.h
new file mode 100644 (file)
index 0000000..998deec
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Emulated 1-byte and 2-byte cmpxchg operations for architectures
+ * lacking direct support for these sizes.  These are implemented in terms
+ * of 4-byte cmpxchg operations.
+ *
+ * Copyright (C) 2024 Paul E. McKenney.
+ */
+
+#ifndef __LINUX_CMPXCHG_EMU_H
+#define __LINUX_CMPXCHG_EMU_H
+
+uintptr_t cmpxchg_emu_u8(volatile u8 *p, uintptr_t old, uintptr_t new);
+
+#endif /* __LINUX_CMPXCHG_EMU_H */
index 2abaa3a825a9ec3f86a69e6e9cf169ad9614b20c..774c2570fe510f9ac07e138a13e8e8455de6373e 100644 (file)
@@ -273,9 +273,27 @@ struct ftrace_likely_data {
  * disable all instrumentation. See Kconfig.kcsan where this is mandatory.
  */
 # define __no_kcsan __no_sanitize_thread __disable_sanitizer_instrumentation
+/*
+ * Type qualifier to mark variables where all data-racy accesses should be
+ * ignored by KCSAN. Note, the implementation simply marks these variables as
+ * volatile, since KCSAN will treat such accesses as "marked".
+ */
+# define __data_racy volatile
 # define __no_sanitize_or_inline __no_kcsan notrace __maybe_unused
 #else
 # define __no_kcsan
+# define __data_racy
+#endif
+
+#ifdef __SANITIZE_MEMORY__
+/*
+ * Similarly to KASAN and KCSAN, KMSAN loses function attributes of inlined
+ * functions, therefore disabling KMSAN checks also requires disabling inlining.
+ *
+ * __no_sanitize_or_inline effectively prevents KMSAN from reporting errors
+ * within the function and marks all its outputs as initialized.
+ */
+# define __no_sanitize_or_inline __no_kmsan_checks notrace __maybe_unused
 #endif
 
 #ifndef __no_sanitize_or_inline
index 272e4e79e15c48db487feba3b7e6103e71b21e8d..861c3bfc5f1700db69d90168c239a935ebad76ca 100644 (file)
@@ -221,7 +221,18 @@ void cpuhp_report_idle_dead(void);
 static inline void cpuhp_report_idle_dead(void) { }
 #endif /* #ifdef CONFIG_HOTPLUG_CPU */
 
+#ifdef CONFIG_CPU_MITIGATIONS
 extern bool cpu_mitigations_off(void);
 extern bool cpu_mitigations_auto_nosmt(void);
+#else
+static inline bool cpu_mitigations_off(void)
+{
+       return true;
+}
+static inline bool cpu_mitigations_auto_nosmt(void)
+{
+       return false;
+}
+#endif
 
 #endif /* _LINUX_CPU_H_ */
index c3f9bb6602ba2135cae645bda4d730cd703a12a6..e06bad467f55ef1befdad569f0a8a37875def383 100644 (file)
@@ -682,11 +682,4 @@ static inline bool dma_fence_is_container(struct dma_fence *fence)
        return dma_fence_is_array(fence) || dma_fence_is_chain(fence);
 }
 
-#define DMA_FENCE_WARN(f, fmt, args...) \
-       do {                                                            \
-               struct dma_fence *__ff = (f);                           \
-               pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
-                        ##args);                                       \
-       } while (0)
-
 #endif /* __LINUX_DMA_FENCE_H */
index 169692cb1906d8015cca7b854c1eaeedb3db09e2..45d0f4800abd417a6fdd9be58988046cb5430ac8 100644 (file)
@@ -84,6 +84,7 @@ static inline void fdput_pos(struct fd f)
 }
 
 DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd)
+DEFINE_CLASS(fd_raw, struct fd, fdput(_T), fdget_raw(fd), int fd)
 
 extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
 extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
index c99bc3df2d28e35f73b21d62ca50f4a53c515e1b..219ee7a76874439e9a2ecda7a402a7a9e741e0be 100644 (file)
@@ -963,6 +963,7 @@ bool bpf_jit_supports_far_kfunc_call(void);
 bool bpf_jit_supports_exceptions(void);
 bool bpf_jit_supports_ptr_xchg(void);
 bool bpf_jit_supports_arena(void);
+u64 bpf_arch_uaddress_limit(void);
 void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp), void *cookie);
 bool bpf_helper_changes_pkt_data(void *func);
 
index 8dfd53b52744a4dfffb8ccb350364972658f00eb..de946a1fd845abe45c403791ae3c823720d9ca13 100644 (file)
@@ -110,23 +110,26 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
  */
 
 /* file is open for reading */
-#define FMODE_READ             ((__force fmode_t)0x1)
+#define FMODE_READ             ((__force fmode_t)(1 << 0))
 /* file is open for writing */
-#define FMODE_WRITE            ((__force fmode_t)0x2)
+#define FMODE_WRITE            ((__force fmode_t)(1 << 1))
 /* file is seekable */
-#define FMODE_LSEEK            ((__force fmode_t)0x4)
+#define FMODE_LSEEK            ((__force fmode_t)(1 << 2))
 /* file can be accessed using pread */
-#define FMODE_PREAD            ((__force fmode_t)0x8)
+#define FMODE_PREAD            ((__force fmode_t)(1 << 3))
 /* file can be accessed using pwrite */
-#define FMODE_PWRITE           ((__force fmode_t)0x10)
+#define FMODE_PWRITE           ((__force fmode_t)(1 << 4))
 /* File is opened for execution with sys_execve / sys_uselib */
-#define FMODE_EXEC             ((__force fmode_t)0x20)
+#define FMODE_EXEC             ((__force fmode_t)(1 << 5))
 /* File writes are restricted (block device specific) */
-#define FMODE_WRITE_RESTRICTED  ((__force fmode_t)0x40)
+#define FMODE_WRITE_RESTRICTED ((__force fmode_t)(1 << 6))
+
+/* FMODE_* bits 7 to 8 */
+
 /* 32bit hashes as llseek() offset (for directories) */
-#define FMODE_32BITHASH         ((__force fmode_t)0x200)
+#define FMODE_32BITHASH         ((__force fmode_t)(1 << 9))
 /* 64bit hashes as llseek() offset (for directories) */
-#define FMODE_64BITHASH         ((__force fmode_t)0x400)
+#define FMODE_64BITHASH         ((__force fmode_t)(1 << 10))
 
 /*
  * Don't update ctime and mtime.
@@ -134,60 +137,53 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
  * Currently a special hack for the XFS open_by_handle ioctl, but we'll
  * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
  */
-#define FMODE_NOCMTIME         ((__force fmode_t)0x800)
+#define FMODE_NOCMTIME         ((__force fmode_t)(1 << 11))
 
 /* Expect random access pattern */
-#define FMODE_RANDOM           ((__force fmode_t)0x1000)
+#define FMODE_RANDOM           ((__force fmode_t)(1 << 12))
 
 /* File is huge (eg. /dev/mem): treat loff_t as unsigned */
-#define FMODE_UNSIGNED_OFFSET  ((__force fmode_t)0x2000)
+#define FMODE_UNSIGNED_OFFSET  ((__force fmode_t)(1 << 13))
 
 /* File is opened with O_PATH; almost nothing can be done with it */
-#define FMODE_PATH             ((__force fmode_t)0x4000)
+#define FMODE_PATH             ((__force fmode_t)(1 << 14))
 
 /* File needs atomic accesses to f_pos */
-#define FMODE_ATOMIC_POS       ((__force fmode_t)0x8000)
+#define FMODE_ATOMIC_POS       ((__force fmode_t)(1 << 15))
 /* Write access to underlying fs */
-#define FMODE_WRITER           ((__force fmode_t)0x10000)
+#define FMODE_WRITER           ((__force fmode_t)(1 << 16))
 /* Has read method(s) */
-#define FMODE_CAN_READ          ((__force fmode_t)0x20000)
+#define FMODE_CAN_READ          ((__force fmode_t)(1 << 17))
 /* Has write method(s) */
-#define FMODE_CAN_WRITE         ((__force fmode_t)0x40000)
+#define FMODE_CAN_WRITE         ((__force fmode_t)(1 << 18))
 
-#define FMODE_OPENED           ((__force fmode_t)0x80000)
-#define FMODE_CREATED          ((__force fmode_t)0x100000)
+#define FMODE_OPENED           ((__force fmode_t)(1 << 19))
+#define FMODE_CREATED          ((__force fmode_t)(1 << 20))
 
 /* File is stream-like */
-#define FMODE_STREAM           ((__force fmode_t)0x200000)
+#define FMODE_STREAM           ((__force fmode_t)(1 << 21))
 
 /* File supports DIRECT IO */
-#define        FMODE_CAN_ODIRECT       ((__force fmode_t)0x400000)
+#define        FMODE_CAN_ODIRECT       ((__force fmode_t)(1 << 22))
 
-#define        FMODE_NOREUSE           ((__force fmode_t)0x800000)
+#define        FMODE_NOREUSE           ((__force fmode_t)(1 << 23))
 
-/* File supports non-exclusive O_DIRECT writes from multiple threads */
-#define FMODE_DIO_PARALLEL_WRITE       ((__force fmode_t)0x1000000)
+/* FMODE_* bit 24 */
 
 /* File is embedded in backing_file object */
-#define FMODE_BACKING          ((__force fmode_t)0x2000000)
+#define FMODE_BACKING          ((__force fmode_t)(1 << 25))
 
 /* File was opened by fanotify and shouldn't generate fanotify events */
-#define FMODE_NONOTIFY         ((__force fmode_t)0x4000000)
+#define FMODE_NONOTIFY         ((__force fmode_t)(1 << 26))
 
 /* File is capable of returning -EAGAIN if I/O will block */
-#define FMODE_NOWAIT           ((__force fmode_t)0x8000000)
+#define FMODE_NOWAIT           ((__force fmode_t)(1 << 27))
 
 /* File represents mount that needs unmounting */
-#define FMODE_NEED_UNMOUNT     ((__force fmode_t)0x10000000)
+#define FMODE_NEED_UNMOUNT     ((__force fmode_t)(1 << 28))
 
 /* File does not contribute to nr_files count */
-#define FMODE_NOACCOUNT                ((__force fmode_t)0x20000000)
-
-/* File supports async buffered reads */
-#define FMODE_BUF_RASYNC       ((__force fmode_t)0x40000000)
-
-/* File supports async nowait buffered writes */
-#define FMODE_BUF_WASYNC       ((__force fmode_t)0x80000000)
+#define FMODE_NOACCOUNT                ((__force fmode_t)(1 << 29))
 
 /*
  * Attribute flags.  These should be or-ed together to figure out what
@@ -1035,12 +1031,13 @@ struct file_handle {
        __u32 handle_bytes;
        int handle_type;
        /* file identifier */
-       unsigned char f_handle[];
+       unsigned char f_handle[] __counted_by(handle_bytes);
 };
 
 static inline struct file *get_file(struct file *f)
 {
-       atomic_long_inc(&f->f_count);
+       long prior = atomic_long_fetch_inc_relaxed(&f->f_count);
+       WARN_ONCE(!prior, "struct file::f_count incremented from zero; use-after-free condition present!\n");
        return f;
 }
 
@@ -2003,8 +2000,11 @@ struct iov_iter;
 struct io_uring_cmd;
 struct offset_ctx;
 
+typedef unsigned int __bitwise fop_flags_t;
+
 struct file_operations {
        struct module *owner;
+       fop_flags_t fop_flags;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
@@ -2017,7 +2017,6 @@ struct file_operations {
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
-       unsigned long mmap_supported_flags;
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *, fl_owner_t id);
        int (*release) (struct inode *, struct file *);
@@ -2048,6 +2047,17 @@ struct file_operations {
                                unsigned int poll_flags);
 } __randomize_layout;
 
+/* Supports async buffered reads */
+#define FOP_BUFFER_RASYNC      ((__force fop_flags_t)(1 << 0))
+/* Supports async buffered writes */
+#define FOP_BUFFER_WASYNC      ((__force fop_flags_t)(1 << 1))
+/* Supports synchronous page faults for mappings */
+#define FOP_MMAP_SYNC          ((__force fop_flags_t)(1 << 2))
+/* Supports non-exclusive O_DIRECT writes from multiple threads */
+#define FOP_DIO_PARALLEL_WRITE ((__force fop_flags_t)(1 << 3))
+/* Contains huge pages */
+#define FOP_HUGE_PAGES         ((__force fop_flags_t)(1 << 4))
+
 /* Wrap a directory iterator that needs exclusive inode access */
 int wrap_directory_iterator(struct file *, struct dir_context *,
                            int (*) (struct file *, struct dir_context *));
@@ -2253,7 +2263,13 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
 
 #define IS_DEADDIR(inode)      ((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)     ((inode)->i_flags & S_NOCMTIME)
+
+#ifdef CONFIG_SWAP
 #define IS_SWAPFILE(inode)     ((inode)->i_flags & S_SWAPFILE)
+#else
+#define IS_SWAPFILE(inode)     ((void)(inode), 0U)
+#endif
+
 #define IS_PRIVATE(inode)      ((inode)->i_flags & S_PRIVATE)
 #define IS_IMA(inode)          ((inode)->i_flags & S_IMA)
 #define IS_AUTOMOUNT(inode)    ((inode)->i_flags & S_AUTOMOUNT)
@@ -3340,6 +3356,8 @@ void simple_offset_init(struct offset_ctx *octx);
 int simple_offset_add(struct offset_ctx *octx, struct dentry *dentry);
 void simple_offset_remove(struct offset_ctx *octx, struct dentry *dentry);
 int simple_offset_empty(struct dentry *dentry);
+int simple_offset_rename(struct inode *old_dir, struct dentry *old_dentry,
+                        struct inode *new_dir, struct dentry *new_dentry);
 int simple_offset_rename_exchange(struct inode *old_dir,
                                  struct dentry *old_dentry,
                                  struct inode *new_dir,
index 01542c4b87a2be065431f60c9f5d1302608a39a7..d3350979115f0a050efe9ee0ad7619c32b5c2f91 100644 (file)
@@ -132,4 +132,8 @@ static inline bool fs_validate_description(const char *name,
 #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)
 
+/* String parameter that allows empty argument */
+#define fsparam_string_empty(NAME, OPT) \
+       __fsparam(fs_param_is_string, NAME, OPT, fs_param_can_be_empty, NULL)
+
 #endif /* _LINUX_FS_PARSER_H */
index 6e8562cbcc43221e50cfd2b5698a99b2f7c2cb3f..9de27643607fb16a20e7ed3dbcd2c564e8e600aa 100644 (file)
@@ -172,9 +172,12 @@ extern void __fscache_invalidate(struct fscache_cookie *, const void *, loff_t,
 extern int __fscache_begin_read_operation(struct netfs_cache_resources *, struct fscache_cookie *);
 extern int __fscache_begin_write_operation(struct netfs_cache_resources *, struct fscache_cookie *);
 
-extern void __fscache_write_to_cache(struct fscache_cookie *, struct address_space *,
-                                    loff_t, size_t, loff_t, netfs_io_terminated_t, void *,
-                                    bool);
+void __fscache_write_to_cache(struct fscache_cookie *cookie,
+                             struct address_space *mapping,
+                             loff_t start, size_t len, loff_t i_size,
+                             netfs_io_terminated_t term_func,
+                             void *term_func_priv,
+                             bool using_pgpriv2, bool cond);
 extern void __fscache_clear_page_bits(struct address_space *, loff_t, size_t);
 
 /**
@@ -597,7 +600,8 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
  * @i_size: The new size of the inode
  * @term_func: The function to call upon completion
  * @term_func_priv: The private data for @term_func
- * @caching: If PG_fscache has been set
+ * @using_pgpriv2: If we're using PG_private_2 to mark in-progress write
+ * @caching: If we actually want to do the caching
  *
  * Helper function for a netfs to write dirty data from an inode into the cache
  * object that's backing it.
@@ -608,19 +612,21 @@ static inline void fscache_clear_page_bits(struct address_space *mapping,
  * marked with PG_fscache.
  *
  * If given, @term_func will be called upon completion and supplied with
- * @term_func_priv.  Note that the PG_fscache flags will have been cleared by
- * this point, so the netfs must retain its own pin on the mapping.
+ * @term_func_priv.  Note that if @using_pgpriv2 is set, the PG_private_2 flags
+ * will have been cleared by this point, so the netfs must retain its own pin
+ * on the mapping.
  */
 static inline void fscache_write_to_cache(struct fscache_cookie *cookie,
                                          struct address_space *mapping,
                                          loff_t start, size_t len, loff_t i_size,
                                          netfs_io_terminated_t term_func,
                                          void *term_func_priv,
-                                         bool caching)
+                                         bool using_pgpriv2, bool caching)
 {
        if (caching)
                __fscache_write_to_cache(cookie, mapping, start, len, i_size,
-                                        term_func, term_func_priv, caching);
+                                        term_func, term_func_priv,
+                                        using_pgpriv2, caching);
        else if (term_func)
                term_func(term_func_priv, -ENOBUFS, false);
 
index 77b30a8c6076b6cf536baf490c613be9a70d8c61..b06f7c426d3829ca07ea1f83e1c6fb98cb337b65 100644 (file)
@@ -554,17 +554,13 @@ static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode)
        return container_of(inode, struct hugetlbfs_inode_info, vfs_inode);
 }
 
-extern const struct file_operations hugetlbfs_file_operations;
 extern const struct vm_operations_struct hugetlb_vm_ops;
 struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct,
                                int creat_flags, int page_size_log);
 
-static inline bool is_file_hugepages(struct file *file)
+static inline bool is_file_hugepages(const struct file *file)
 {
-       if (file->f_op == &hugetlbfs_file_operations)
-               return true;
-
-       return is_file_shm_hugepages(file);
+       return file->f_op->fop_flags & FOP_HUGE_PAGES;
 }
 
 static inline struct hstate *hstate_inode(struct inode *i)
index 74e0cc14ebf86bb9444b54d628908f976125ff3f..967aa9ea9f960dbb5105bb18051af87e8ef5184c 100644 (file)
@@ -44,6 +44,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT};
 #define LOOKUP_BENEATH         0x080000 /* No escaping from starting point. */
 #define LOOKUP_IN_ROOT         0x100000 /* Treat dirfd as fs root. */
 #define LOOKUP_CACHED          0x200000 /* Only do cached lookup */
+#define LOOKUP_LINKAT_EMPTY    0x400000 /* Linkat request with empty path. */
 /* LOOKUP_* flags which do scope-related checks based on the dirfd. */
 #define LOOKUP_IS_SCOPED (LOOKUP_BENEATH | LOOKUP_IN_ROOT)
 
index 100cbb261269d1921bff6e616e86223ee9e5512c..ca56a4428043d58392954fbfbedd43178cde7a74 100644 (file)
 #include <linux/uio.h>
 
 enum netfs_sreq_ref_trace;
-
-/*
- * Overload PG_private_2 to give us PG_fscache - this is used to indicate that
- * a page is currently backed by a local disk cache
- */
-#define folio_test_fscache(folio)      folio_test_private_2(folio)
-#define PageFsCache(page)              PagePrivate2((page))
-#define SetPageFsCache(page)           SetPagePrivate2((page))
-#define ClearPageFsCache(page)         ClearPagePrivate2((page))
-#define TestSetPageFsCache(page)       TestSetPagePrivate2((page))
-#define TestClearPageFsCache(page)     TestClearPagePrivate2((page))
+typedef struct mempool_s mempool_t;
 
 /**
- * folio_start_fscache - Start an fscache write on a folio.
+ * folio_start_private_2 - Start an fscache write on a folio.  [DEPRECATED]
  * @folio: The folio.
  *
  * Call this function before writing a folio to a local cache.  Starting a
  * second write before the first one finishes is not allowed.
+ *
+ * Note that this should no longer be used.
  */
-static inline void folio_start_fscache(struct folio *folio)
+static inline void folio_start_private_2(struct folio *folio)
 {
        VM_BUG_ON_FOLIO(folio_test_private_2(folio), folio);
        folio_get(folio);
        folio_set_private_2(folio);
 }
 
-/**
- * folio_end_fscache - End an fscache write on a folio.
- * @folio: The folio.
- *
- * Call this function after the folio has been written to the local cache.
- * This will wake any sleepers waiting on this folio.
- */
-static inline void folio_end_fscache(struct folio *folio)
-{
-       folio_end_private_2(folio);
-}
-
-/**
- * folio_wait_fscache - Wait for an fscache write on this folio to end.
- * @folio: The folio.
- *
- * If this folio is currently being written to a local cache, wait for
- * the write to finish.  Another write may start after this one finishes,
- * unless the caller holds the folio lock.
- */
-static inline void folio_wait_fscache(struct folio *folio)
-{
-       folio_wait_private_2(folio);
-}
-
-/**
- * folio_wait_fscache_killable - Wait for an fscache write on this folio to end.
- * @folio: The folio.
- *
- * If this folio is currently being written to a local cache, wait
- * for the write to finish or for a fatal signal to be received.
- * Another write may start after this one finishes, unless the caller
- * holds the folio lock.
- *
- * Return:
- * - 0 if successful.
- * - -EINTR if a fatal signal was encountered.
- */
-static inline int folio_wait_fscache_killable(struct folio *folio)
-{
-       return folio_wait_private_2_killable(folio);
-}
-
-static inline void set_page_fscache(struct page *page)
-{
-       folio_start_fscache(page_folio(page));
-}
-
-static inline void end_page_fscache(struct page *page)
-{
-       folio_end_private_2(page_folio(page));
-}
-
-static inline void wait_on_page_fscache(struct page *page)
-{
-       folio_wait_private_2(page_folio(page));
-}
-
-static inline int wait_on_page_fscache_killable(struct page *page)
-{
-       return folio_wait_private_2_killable(page_folio(page));
-}
-
 /* Marks used on xarray-based buffers */
 #define NETFS_BUF_PUT_MARK     XA_MARK_0       /* - Page needs putting  */
 #define NETFS_BUF_PAGECACHE_MARK XA_MARK_1     /* - Page needs wb/dirty flag wrangling */
@@ -135,6 +64,7 @@ struct netfs_inode {
 #if IS_ENABLED(CONFIG_FSCACHE)
        struct fscache_cookie   *cache;
 #endif
+       struct mutex            wb_lock;        /* Writeback serialisation */
        loff_t                  remote_i_size;  /* Size of the remote file */
        loff_t                  zero_point;     /* Size after which we assume there's no data
                                                 * on the server */
@@ -142,7 +72,8 @@ struct netfs_inode {
 #define NETFS_ICTX_ODIRECT     0               /* The file has DIO in progress */
 #define NETFS_ICTX_UNBUFFERED  1               /* I/O should not use the pagecache */
 #define NETFS_ICTX_WRITETHROUGH        2               /* Write-through caching */
-#define NETFS_ICTX_NO_WRITE_STREAMING  3       /* Don't engage in write-streaming */
+#define NETFS_ICTX_USE_PGPRIV2 31              /* [DEPRECATED] Use PG_private_2 to mark
+                                                * write to cache on read */
 };
 
 /*
@@ -165,16 +96,25 @@ struct netfs_folio {
        unsigned int            dirty_len;      /* Write-streaming dirty data length */
 };
 #define NETFS_FOLIO_INFO       0x1UL   /* OR'd with folio->private. */
+#define NETFS_FOLIO_COPY_TO_CACHE ((struct netfs_group *)0x356UL) /* Write to the cache only */
 
-static inline struct netfs_folio *netfs_folio_info(struct folio *folio)
+static inline bool netfs_is_folio_info(const void *priv)
 {
-       void *priv = folio_get_private(folio);
+       return (unsigned long)priv & NETFS_FOLIO_INFO;
+}
 
-       if ((unsigned long)priv & NETFS_FOLIO_INFO)
+static inline struct netfs_folio *__netfs_folio_info(const void *priv)
+{
+       if (netfs_is_folio_info(priv))
                return (struct netfs_folio *)((unsigned long)priv & ~NETFS_FOLIO_INFO);
        return NULL;
 }
 
+static inline struct netfs_folio *netfs_folio_info(struct folio *folio)
+{
+       return __netfs_folio_info(folio_get_private(folio));
+}
+
 static inline struct netfs_group *netfs_folio_group(struct folio *folio)
 {
        struct netfs_folio *finfo;
@@ -186,6 +126,33 @@ static inline struct netfs_group *netfs_folio_group(struct folio *folio)
        return priv;
 }
 
+/*
+ * Stream of I/O subrequests going to a particular destination, such as the
+ * server or the local cache.  This is mainly intended for writing where we may
+ * have to write to multiple destinations concurrently.
+ */
+struct netfs_io_stream {
+       /* Submission tracking */
+       struct netfs_io_subrequest *construct;  /* Op being constructed */
+       unsigned int            submit_off;     /* Folio offset we're submitting from */
+       unsigned int            submit_len;     /* Amount of data left to submit */
+       unsigned int            submit_max_len; /* Amount I/O can be rounded up to */
+       void (*prepare_write)(struct netfs_io_subrequest *subreq);
+       void (*issue_write)(struct netfs_io_subrequest *subreq);
+       /* Collection tracking */
+       struct list_head        subrequests;    /* Contributory I/O operations */
+       struct netfs_io_subrequest *front;      /* Op being collected */
+       unsigned long long      collected_to;   /* Position we've collected results to */
+       size_t                  transferred;    /* The amount transferred from this stream */
+       enum netfs_io_source    source;         /* Where to read from/write to */
+       unsigned short          error;          /* Aggregate error for the stream */
+       unsigned char           stream_nr;      /* Index of stream in parent table */
+       bool                    avail;          /* T if stream is available */
+       bool                    active;         /* T if stream is active */
+       bool                    need_retry;     /* T if this stream needs retrying */
+       bool                    failed;         /* T if this stream failed */
+};
+
 /*
  * Resources required to do operations on a cache.
  */
@@ -209,14 +176,17 @@ struct netfs_io_subrequest {
        struct work_struct      work;
        struct list_head        rreq_link;      /* Link in rreq->subrequests */
        struct iov_iter         io_iter;        /* Iterator for this subrequest */
-       loff_t                  start;          /* Where to start the I/O */
+       unsigned long long      start;          /* Where to start the I/O */
+       size_t                  max_len;        /* Maximum size of the I/O */
        size_t                  len;            /* Size of the I/O */
        size_t                  transferred;    /* Amount of data transferred */
        refcount_t              ref;
        short                   error;          /* 0 or error that occurred */
        unsigned short          debug_index;    /* Index in list (for debugging output) */
+       unsigned int            nr_segs;        /* Number of segs in io_iter */
        unsigned int            max_nr_segs;    /* 0 or max number of segments in an iterator */
        enum netfs_io_source    source;         /* Where to read from/write to */
+       unsigned char           stream_nr;      /* I/O stream this belongs to */
        unsigned long           flags;
 #define NETFS_SREQ_COPY_TO_CACHE       0       /* Set if should copy the data to the cache */
 #define NETFS_SREQ_CLEAR_TAIL          1       /* Set if the rest of the read should be cleared */
@@ -224,15 +194,20 @@ struct netfs_io_subrequest {
 #define NETFS_SREQ_SEEK_DATA_READ      3       /* Set if ->read() should SEEK_DATA first */
 #define NETFS_SREQ_NO_PROGRESS         4       /* Set if we didn't manage to read any data */
 #define NETFS_SREQ_ONDEMAND            5       /* Set if it's from on-demand read mode */
+#define NETFS_SREQ_BOUNDARY            6       /* Set if ends on hard boundary (eg. ceph object) */
+#define NETFS_SREQ_IN_PROGRESS         8       /* Unlocked when the subrequest completes */
+#define NETFS_SREQ_NEED_RETRY          9       /* Set if the filesystem requests a retry */
+#define NETFS_SREQ_RETRYING            10      /* Set if we're retrying */
+#define NETFS_SREQ_FAILED              11      /* Set if the subreq failed unretryably */
 };
 
 enum netfs_io_origin {
        NETFS_READAHEAD,                /* This read was triggered by readahead */
        NETFS_READPAGE,                 /* This read is a synchronous read */
        NETFS_READ_FOR_WRITE,           /* This read is to prepare a write */
+       NETFS_COPY_TO_CACHE,            /* This write is to copy a read to the cache */
        NETFS_WRITEBACK,                /* This write was triggered by writepages */
        NETFS_WRITETHROUGH,             /* This write was made by netfs_perform_write() */
-       NETFS_LAUNDER_WRITE,            /* This is triggered by ->launder_folio() */
        NETFS_UNBUFFERED_WRITE,         /* This is an unbuffered write */
        NETFS_DIO_READ,                 /* This is a direct I/O read */
        NETFS_DIO_WRITE,                /* This is a direct I/O write */
@@ -254,26 +229,36 @@ struct netfs_io_request {
        struct netfs_cache_resources cache_resources;
        struct list_head        proc_link;      /* Link in netfs_iorequests */
        struct list_head        subrequests;    /* Contributory I/O operations */
+       struct netfs_io_stream  io_streams[2];  /* Streams of parallel I/O operations */
+#define NR_IO_STREAMS 2 //wreq->nr_io_streams
+       struct netfs_group      *group;         /* Writeback group being written back */
        struct iov_iter         iter;           /* Unencrypted-side iterator */
        struct iov_iter         io_iter;        /* I/O (Encrypted-side) iterator */
        void                    *netfs_priv;    /* Private data for the netfs */
+       void                    *netfs_priv2;   /* Private data for the netfs */
        struct bio_vec          *direct_bv;     /* DIO buffer list (when handling iovec-iter) */
        unsigned int            direct_bv_count; /* Number of elements in direct_bv[] */
        unsigned int            debug_id;
        unsigned int            rsize;          /* Maximum read size (0 for none) */
        unsigned int            wsize;          /* Maximum write size (0 for none) */
-       unsigned int            subreq_counter; /* Next subreq->debug_index */
+       atomic_t                subreq_counter; /* Next subreq->debug_index */
+       unsigned int            nr_group_rel;   /* Number of refs to release on ->group */
+       spinlock_t              lock;           /* Lock for queuing subreqs */
        atomic_t                nr_outstanding; /* Number of ops in progress */
        atomic_t                nr_copy_ops;    /* Number of copy-to-cache ops in progress */
-       size_t                  submitted;      /* Amount submitted for I/O so far */
-       size_t                  len;            /* Length of the request */
        size_t                  upper_len;      /* Length can be extended to here */
+       unsigned long long      submitted;      /* Amount submitted for I/O so far */
+       unsigned long long      len;            /* Length of the request */
        size_t                  transferred;    /* Amount to be indicated as transferred */
        short                   error;          /* 0 or error that occurred */
        enum netfs_io_origin    origin;         /* Origin of the request */
        bool                    direct_bv_unpin; /* T if direct_bv[] must be unpinned */
-       loff_t                  i_size;         /* Size of the file */
-       loff_t                  start;          /* Start position */
+       unsigned long long      i_size;         /* Size of the file */
+       unsigned long long      start;          /* Start position */
+       atomic64_t              issued_to;      /* Write issuer folio cursor */
+       unsigned long long      contiguity;     /* Tracking for gaps in the writeback sequence */
+       unsigned long long      collected_to;   /* Point we've collected to */
+       unsigned long long      cleaned_to;     /* Position we've cleaned folios to */
        pgoff_t                 no_unlock_folio; /* Don't unlock this folio after read */
        refcount_t              ref;
        unsigned long           flags;
@@ -287,6 +272,11 @@ struct netfs_io_request {
 #define NETFS_RREQ_UPLOAD_TO_SERVER    8       /* Need to write to the server */
 #define NETFS_RREQ_NONBLOCK            9       /* Don't block if possible (O_NONBLOCK) */
 #define NETFS_RREQ_BLOCKED             10      /* We blocked */
+#define NETFS_RREQ_PAUSE               11      /* Pause subrequest generation */
+#define NETFS_RREQ_USE_IO_ITER         12      /* Use ->io_iter rather than ->i_pages */
+#define NETFS_RREQ_ALL_QUEUED          13      /* All subreqs are now queued */
+#define NETFS_RREQ_USE_PGPRIV2         31      /* [DEPRECATED] Use PG_private_2 to mark
+                                                * write to cache on read */
        const struct netfs_request_ops *netfs_ops;
        void (*cleanup)(struct netfs_io_request *req);
 };
@@ -295,8 +285,8 @@ struct netfs_io_request {
  * Operations the network filesystem can/must provide to the helpers.
  */
 struct netfs_request_ops {
-       unsigned int    io_request_size;        /* Alloc size for netfs_io_request struct */
-       unsigned int    io_subrequest_size;     /* Alloc size for netfs_io_subrequest struct */
+       mempool_t *request_pool;
+       mempool_t *subrequest_pool;
        int (*init_request)(struct netfs_io_request *rreq, struct file *file);
        void (*free_request)(struct netfs_io_request *rreq);
        void (*free_subrequest)(struct netfs_io_subrequest *rreq);
@@ -312,10 +302,13 @@ struct netfs_request_ops {
 
        /* Modification handling */
        void (*update_i_size)(struct inode *inode, loff_t i_size);
+       void (*post_modify)(struct inode *inode);
 
        /* Write request handling */
-       void (*create_write_requests)(struct netfs_io_request *wreq,
-                                     loff_t start, size_t len);
+       void (*begin_writeback)(struct netfs_io_request *wreq);
+       void (*prepare_write)(struct netfs_io_subrequest *subreq);
+       void (*issue_write)(struct netfs_io_subrequest *subreq);
+       void (*retry_request)(struct netfs_io_request *wreq, struct netfs_io_stream *stream);
        void (*invalidate_cache)(struct netfs_io_request *wreq);
 };
 
@@ -350,15 +343,27 @@ struct netfs_cache_ops {
                     netfs_io_terminated_t term_func,
                     void *term_func_priv);
 
+       /* Write data to the cache from a netfs subrequest. */
+       void (*issue_write)(struct netfs_io_subrequest *subreq);
+
        /* Expand readahead request */
        void (*expand_readahead)(struct netfs_cache_resources *cres,
-                                loff_t *_start, size_t *_len, loff_t i_size);
+                                unsigned long long *_start,
+                                unsigned long long *_len,
+                                unsigned long long i_size);
 
        /* Prepare a read operation, shortening it to a cached/uncached
         * boundary as appropriate.
         */
        enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq,
-                                            loff_t i_size);
+                                            unsigned long long i_size);
+
+       /* Prepare a write subrequest, working out if we're allowed to do it
+        * and finding out the maximum amount of data to gather before
+        * attempting to submit.  If we're not permitted to do it, the
+        * subrequest should be marked failed.
+        */
+       void (*prepare_write_subreq)(struct netfs_io_subrequest *subreq);
 
        /* Prepare a write operation, working out what part of the write we can
         * actually do.
@@ -384,6 +389,7 @@ struct netfs_cache_ops {
 };
 
 /* High-level read API. */
+ssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter);
 ssize_t netfs_unbuffered_read_iter(struct kiocb *iocb, struct iov_iter *iter);
 ssize_t netfs_buffered_read_iter(struct kiocb *iocb, struct iov_iter *iter);
 ssize_t netfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter);
@@ -410,7 +416,6 @@ int netfs_unpin_writeback(struct inode *inode, struct writeback_control *wbc);
 void netfs_clear_inode_writeback(struct inode *inode, const void *aux);
 void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length);
 bool netfs_release_folio(struct folio *folio, gfp_t gfp);
-int netfs_launder_folio(struct folio *folio);
 
 /* VMA operations API. */
 vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group);
@@ -426,9 +431,7 @@ ssize_t netfs_extract_user_iter(struct iov_iter *orig, size_t orig_len,
                                iov_iter_extraction_t extraction_flags);
 size_t netfs_limit_iter(const struct iov_iter *iter, size_t start_offset,
                        size_t max_size, size_t max_segs);
-struct netfs_io_subrequest *netfs_create_write_request(
-       struct netfs_io_request *wreq, enum netfs_io_source dest,
-       loff_t start, size_t len, work_func_t worker);
+void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);
 void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error,
                                       bool was_async);
 void netfs_queue_write_request(struct netfs_io_subrequest *subreq);
@@ -472,6 +475,7 @@ static inline void netfs_inode_init(struct netfs_inode *ctx,
 #if IS_ENABLED(CONFIG_FSCACHE)
        ctx->cache = NULL;
 #endif
+       mutex_init(&ctx->wb_lock);
        /* ->releasepage() drives zero_point */
        if (use_zero_point) {
                ctx->zero_point = ctx->remote_i_size;
index 2df35e65557d27c19fc3d87e865bc869b87bd18c..c5e33e2ca48a0088358e4fbaddca4023885743b7 100644 (file)
@@ -40,6 +40,8 @@ int filemap_fdatawait_keep_errors(struct address_space *mapping);
 int filemap_fdatawait_range(struct address_space *, loff_t lstart, loff_t lend);
 int filemap_fdatawait_range_keep_errors(struct address_space *mapping,
                loff_t start_byte, loff_t end_byte);
+int filemap_invalidate_inode(struct inode *inode, bool flush,
+                            loff_t start, loff_t end);
 
 static inline int filemap_fdatawait(struct address_space *mapping)
 {
index a0c75e467df36f168f3aa920e6edcc2e1f70ef84..c547d1d4feb1e28bf1efe0d083242a230fb48dc5 100644 (file)
 #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F3 0x12fb
 #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3 0x12c3
 #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3 0x16fb
+#define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3 0x12bb
 #define PCI_DEVICE_ID_AMD_MI200_DF_F3  0x14d3
 #define PCI_DEVICE_ID_AMD_MI300_DF_F3  0x152b
 #define PCI_DEVICE_ID_AMD_VANGOGH_USB  0x163a
index eb556f988d5768b72ec5c20770ac3c61c6817152..d8f15770a522b5eb8a8c1c2e834fe792f94dba39 100644 (file)
@@ -71,7 +71,6 @@ struct sysc_regbits {
 #define SYSC_QUIRK_SWSUP_SIDLE_ACT     BIT(12)
 #define SYSC_QUIRK_SWSUP_SIDLE         BIT(11)
 #define SYSC_QUIRK_EXT_OPT_CLOCK       BIT(10)
-#define SYSC_QUIRK_LEGACY_IDLE         BIT(9)
 #define SYSC_QUIRK_RESET_STATUS                BIT(8)
 #define SYSC_QUIRK_NO_IDLE             BIT(7)
 #define SYSC_QUIRK_NO_IDLE_ON_INIT     BIT(6)
index 17d7ed5f3ae6e5c612acd4261be763855069946d..dfd2399f2cde03f9807cd8aec2189b84f8e130fc 100644 (file)
@@ -401,15 +401,15 @@ static inline int debug_lockdep_rcu_enabled(void)
                }                                                       \
        } while (0)
 
-#if defined(CONFIG_PROVE_RCU) && !defined(CONFIG_PREEMPT_RCU)
+#ifndef CONFIG_PREEMPT_RCU
 static inline void rcu_preempt_sleep_check(void)
 {
        RCU_LOCKDEP_WARN(lock_is_held(&rcu_lock_map),
                         "Illegal context switch in RCU read-side critical section");
 }
-#else /* #ifdef CONFIG_PROVE_RCU */
+#else // #ifndef CONFIG_PREEMPT_RCU
 static inline void rcu_preempt_sleep_check(void) { }
-#endif /* #else #ifdef CONFIG_PROVE_RCU */
+#endif // #else // #ifndef CONFIG_PREEMPT_RCU
 
 #define rcu_sleep_check()                                              \
        do {                                                            \
@@ -809,9 +809,9 @@ static inline void rcu_read_unlock(void)
 {
        RCU_LOCKDEP_WARN(!rcu_is_watching(),
                         "rcu_read_unlock() used illegally while idle");
+       rcu_lock_release(&rcu_lock_map); /* Keep acq info for rls diags. */
        __release(RCU);
        __rcu_read_unlock();
-       rcu_lock_release(&rcu_lock_map); /* Keep acq info for rls diags. */
 }
 
 /**
@@ -1090,6 +1090,18 @@ rcu_head_after_call_rcu(struct rcu_head *rhp, rcu_callback_t f)
 extern int rcu_expedited;
 extern int rcu_normal;
 
-DEFINE_LOCK_GUARD_0(rcu, rcu_read_lock(), rcu_read_unlock())
+DEFINE_LOCK_GUARD_0(rcu,
+       do {
+               rcu_read_lock();
+               /*
+                * sparse doesn't call the cleanup function,
+                * so just release immediately and don't track
+                * the context. We don't need to anyway, since
+                * the whole point of the guard is to not need
+                * the explicit unlock.
+                */
+               __release(RCU);
+       } while (0),
+       rcu_read_unlock())
 
 #endif /* __LINUX_RCUPDATE_H */
index d07f0848802e58c650371f0faf3288c3cc35f4b1..303ab9bee15520c4710dec99f4d5df7258f531d8 100644 (file)
@@ -19,18 +19,18 @@ struct rcu_synchronize {
 };
 void wakeme_after_rcu(struct rcu_head *head);
 
-void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
+void __wait_rcu_gp(bool checktiny, unsigned int state, int n, call_rcu_func_t *crcu_array,
                   struct rcu_synchronize *rs_array);
 
-#define _wait_rcu_gp(checktiny, ...) \
-do {                                                                   \
-       call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };               \
-       struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];    \
-       __wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array),              \
-                       __crcu_array, __rs_array);                      \
+#define _wait_rcu_gp(checktiny, state, ...) \
+do {                                                                                           \
+       call_rcu_func_t __crcu_array[] = { __VA_ARGS__ };                                       \
+       struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)];                            \
+       __wait_rcu_gp(checktiny, state, ARRAY_SIZE(__crcu_array), __crcu_array, __rs_array);    \
 } while (0)
 
-#define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__)
+#define wait_rcu_gp(...) _wait_rcu_gp(false, TASK_UNINTERRUPTIBLE, __VA_ARGS__)
+#define wait_rcu_gp_state(state, ...) _wait_rcu_gp(false, state, __VA_ARGS__)
 
 /**
  * synchronize_rcu_mult - Wait concurrently for multiple grace periods
@@ -54,7 +54,7 @@ do {                                                                  \
  * grace period.
  */
 #define synchronize_rcu_mult(...) \
-       _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__)
+       _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), TASK_UNINTERRUPTIBLE, __VA_ARGS__)
 
 static inline void cond_resched_rcu(void)
 {
index b743241cfb7caa22da0e12098da3ea7dead08a9b..d470303b1bbbbe9d3e468cab99cdb3e72067d66f 100644 (file)
@@ -1230,6 +1230,7 @@ int regmap_multi_reg_write_bypassed(struct regmap *map,
 int regmap_raw_write_async(struct regmap *map, unsigned int reg,
                           const void *val, size_t val_len);
 int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
+int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val);
 int regmap_raw_read(struct regmap *map, unsigned int reg,
                    void *val, size_t val_len);
 int regmap_noinc_read(struct regmap *map, unsigned int reg,
@@ -1739,6 +1740,13 @@ static inline int regmap_read(struct regmap *map, unsigned int reg,
        return -EINVAL;
 }
 
+static inline int regmap_read_bypassed(struct regmap *map, unsigned int reg,
+                                      unsigned int *val)
+{
+       WARN_ONCE(1, "regmap API is disabled");
+       return -EINVAL;
+}
+
 static inline int regmap_raw_read(struct regmap *map, unsigned int reg,
                                  void *val, size_t val_len)
 {
index 4660582a33022fc15946a811105318199ccaca42..ed180ca419dad94d6e7db7eae820a26f8dcc5e48 100644 (file)
@@ -320,13 +320,13 @@ devm_regulator_get_exclusive(struct device *dev, const char *id)
 
 static inline int devm_regulator_get_enable(struct device *dev, const char *id)
 {
-       return -ENODEV;
+       return 0;
 }
 
 static inline int devm_regulator_get_enable_optional(struct device *dev,
                                                     const char *id)
 {
-       return -ENODEV;
+       return 0;
 }
 
 static inline struct regulator *__must_check
index b807141acc1404b26346c74315db47302fe314d0..3a9bb5b9a9e8f8116f578bb72919bb92a76cc6fc 100644 (file)
@@ -737,6 +737,89 @@ struct scmi_powercap_proto_ops {
                                          u32 *power_thresh_high);
 };
 
+enum scmi_pinctrl_selector_type {
+       PIN_TYPE = 0,
+       GROUP_TYPE,
+       FUNCTION_TYPE,
+};
+
+enum scmi_pinctrl_conf_type {
+       SCMI_PIN_DEFAULT = 0,
+       SCMI_PIN_BIAS_BUS_HOLD = 1,
+       SCMI_PIN_BIAS_DISABLE = 2,
+       SCMI_PIN_BIAS_HIGH_IMPEDANCE = 3,
+       SCMI_PIN_BIAS_PULL_UP = 4,
+       SCMI_PIN_BIAS_PULL_DEFAULT = 5,
+       SCMI_PIN_BIAS_PULL_DOWN = 6,
+       SCMI_PIN_DRIVE_OPEN_DRAIN = 7,
+       SCMI_PIN_DRIVE_OPEN_SOURCE = 8,
+       SCMI_PIN_DRIVE_PUSH_PULL = 9,
+       SCMI_PIN_DRIVE_STRENGTH = 10,
+       SCMI_PIN_INPUT_DEBOUNCE = 11,
+       SCMI_PIN_INPUT_MODE = 12,
+       SCMI_PIN_PULL_MODE = 13,
+       SCMI_PIN_INPUT_VALUE = 14,
+       SCMI_PIN_INPUT_SCHMITT = 15,
+       SCMI_PIN_LOW_POWER_MODE = 16,
+       SCMI_PIN_OUTPUT_MODE = 17,
+       SCMI_PIN_OUTPUT_VALUE = 18,
+       SCMI_PIN_POWER_SOURCE = 19,
+       SCMI_PIN_SLEW_RATE = 20,
+       SCMI_PIN_OEM_START = 192,
+       SCMI_PIN_OEM_END = 255,
+};
+
+/**
+ * struct scmi_pinctrl_proto_ops - represents the various operations provided
+ * by SCMI Pinctrl Protocol
+ *
+ * @count_get: returns count of the registered elements in given type
+ * @name_get: returns name by index of given type
+ * @group_pins_get: returns the set of pins, assigned to the specified group
+ * @function_groups_get: returns the set of groups, assigned to the specified
+ *     function
+ * @mux_set: set muxing function for groups of pins
+ * @settings_get_one: returns one configuration parameter for pin or group
+ *     specified by config_type
+ * @settings_get_all: returns all configuration parameters for pin or group
+ * @settings_conf: sets the configuration parameter for pin or group
+ * @pin_request: aquire pin before selecting mux setting
+ * @pin_free: frees pin, acquired by request_pin call
+ */
+struct scmi_pinctrl_proto_ops {
+       int (*count_get)(const struct scmi_protocol_handle *ph,
+                        enum scmi_pinctrl_selector_type type);
+       int (*name_get)(const struct scmi_protocol_handle *ph, u32 selector,
+                       enum scmi_pinctrl_selector_type type,
+                       const char **name);
+       int (*group_pins_get)(const struct scmi_protocol_handle *ph,
+                             u32 selector, const unsigned int **pins,
+                             unsigned int *nr_pins);
+       int (*function_groups_get)(const struct scmi_protocol_handle *ph,
+                                  u32 selector, unsigned int *nr_groups,
+                                  const unsigned int **groups);
+       int (*mux_set)(const struct scmi_protocol_handle *ph, u32 selector,
+                      u32 group);
+       int (*settings_get_one)(const struct scmi_protocol_handle *ph,
+                               u32 selector,
+                               enum scmi_pinctrl_selector_type type,
+                               enum scmi_pinctrl_conf_type config_type,
+                               u32 *config_value);
+       int (*settings_get_all)(const struct scmi_protocol_handle *ph,
+                               u32 selector,
+                               enum scmi_pinctrl_selector_type type,
+                               unsigned int *nr_configs,
+                               enum scmi_pinctrl_conf_type *config_types,
+                               u32 *config_values);
+       int (*settings_conf)(const struct scmi_protocol_handle *ph,
+                            u32 selector, enum scmi_pinctrl_selector_type type,
+                            unsigned int nr_configs,
+                            enum scmi_pinctrl_conf_type *config_type,
+                            u32 *config_value);
+       int (*pin_request)(const struct scmi_protocol_handle *ph, u32 pin);
+       int (*pin_free)(const struct scmi_protocol_handle *ph, u32 pin);
+};
+
 /**
  * struct scmi_notify_ops  - represents notifications' operations provided by
  * SCMI core
@@ -783,8 +866,6 @@ struct scmi_notify_ops {
                                            const u32 *src_id,
                                            struct notifier_block *nb);
        int (*devm_event_notifier_unregister)(struct scmi_device *sdev,
-                                             u8 proto_id, u8 evt_id,
-                                             const u32 *src_id,
                                              struct notifier_block *nb);
        int (*event_notifier_register)(const struct scmi_handle *handle,
                                       u8 proto_id, u8 evt_id,
@@ -844,6 +925,7 @@ enum scmi_std_protocol {
        SCMI_PROTOCOL_RESET = 0x16,
        SCMI_PROTOCOL_VOLTAGE = 0x17,
        SCMI_PROTOCOL_POWERCAP = 0x18,
+       SCMI_PROTOCOL_PINCTRL = 0x19,
 };
 
 enum scmi_system_events {
index 234bcdb1fba459916635067154bedd17d8cfd423..8bd4fda6e02752433832ef78d1afb0cea7870178 100644 (file)
@@ -118,7 +118,18 @@ void seq_vprintf(struct seq_file *m, const char *fmt, va_list args);
 __printf(2, 3)
 void seq_printf(struct seq_file *m, const char *fmt, ...);
 void seq_putc(struct seq_file *m, char c);
-void seq_puts(struct seq_file *m, const char *s);
+void __seq_puts(struct seq_file *m, const char *s);
+
+static __always_inline void seq_puts(struct seq_file *m, const char *s)
+{
+       if (!__builtin_constant_p(*s))
+               __seq_puts(m, s);
+       else if (s[0] && !s[1])
+               seq_putc(m, s[0]);
+       else
+               seq_write(m, s, __builtin_strlen(s));
+}
+
 void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
                               unsigned long long num, unsigned int width);
 void seq_put_decimal_ull(struct seq_file *m, const char *delimiter,
index c55bef0538e58427cdc2c2193ce3b96b3c9b4b80..1d3d3ae958fbd3a4334a26ed597e44b640d8b96e 100644 (file)
@@ -16,7 +16,6 @@ struct sysv_shm {
 
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr,
              unsigned long shmlba);
-bool is_file_shm_hugepages(struct file *file);
 void exit_shm(struct task_struct *task);
 #define shm_init_task(task) INIT_LIST_HEAD(&(task)->sysvshm.shm_clist)
 #else
@@ -30,10 +29,6 @@ static inline long do_shmat(int shmid, char __user *shmaddr,
 {
        return -ENOSYS;
 }
-static inline bool is_file_shm_hugepages(struct file *file)
-{
-       return false;
-}
 static inline void exit_shm(struct task_struct *task)
 {
 }
index 9d24aec064e888316b5a5cf450cf25ffdd391183..4ff48eda3f642dac705307958c2883f3cdb07ab5 100644 (file)
@@ -3031,6 +3031,21 @@ static inline void skb_mac_header_rebuild(struct sk_buff *skb)
        }
 }
 
+/* Move the full mac header up to current network_header.
+ * Leaves skb->data pointing at offset skb->mac_len into the mac_header.
+ * Must be provided the complete mac header length.
+ */
+static inline void skb_mac_header_rebuild_full(struct sk_buff *skb, u32 full_mac_len)
+{
+       if (skb_mac_header_was_set(skb)) {
+               const unsigned char *old_mac = skb_mac_header(skb);
+
+               skb_set_mac_header(skb, -full_mac_len);
+               memmove(skb_mac_header(skb), old_mac, full_mac_len);
+               __skb_push(skb, full_mac_len - skb->mac_len);
+       }
+}
+
 static inline int skb_checksum_start_offset(const struct sk_buff *skb)
 {
        return skb->csum_start - skb_headroom(skb);
index e65ec3fd27998a5b82fc2c4597c575125e653056..a509caf823d6188070d17da6c7724f6d07eb0997 100644 (file)
@@ -461,10 +461,12 @@ static inline void sk_psock_put(struct sock *sk, struct sk_psock *psock)
 
 static inline void sk_psock_data_ready(struct sock *sk, struct sk_psock *psock)
 {
+       read_lock_bh(&sk->sk_callback_lock);
        if (psock->saved_data_ready)
                psock->saved_data_ready(sk);
        else
                sk->sk_data_ready(sk);
+       read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static inline void psock_set_prog(struct bpf_prog **pprog,
index e53cbfa18325587fdf1363cae60066a11959c7df..739b21262507793412fbc1987e2df017148c1b07 100644 (file)
@@ -266,7 +266,7 @@ void kfree(const void *objp);
 void kfree_sensitive(const void *objp);
 size_t __ksize(const void *objp);
 
-DEFINE_FREE(kfree, void *, if (_T) kfree(_T))
+DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T))
 
 /**
  * ksize - Report actual allocation size of associated object
@@ -792,7 +792,7 @@ static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, gfp_t fla
 extern void *kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags)
                      __realloc_size(3);
 extern void kvfree(const void *addr);
-DEFINE_FREE(kvfree, void *, if (_T) kvfree(_T))
+DEFINE_FREE(kvfree, void *, if (!IS_ERR_OR_NULL(_T)) kvfree(_T))
 
 extern void kvfree_sensitive(const void *addr, size_t len);
 
index 649955d2cf5cdd89de731d4b402d7bda22e0f93c..d4a8e34505e6bdea98e38f76558ee8e9c260daa3 100644 (file)
 #define CMDQ_ADDR_HIGH(addr)   ((u32)(((addr) >> 16) & GENMASK(31, 0)))
 #define CMDQ_ADDR_LOW(addr)    ((u16)(addr) | BIT(1))
 
+/*
+ * Every cmdq thread has its own SPRs (Specific Purpose Registers),
+ * so there are 4 * N (threads) SPRs in GCE that shares the same indexes below.
+ */
+#define CMDQ_THR_SPR_IDX0      (0)
+#define CMDQ_THR_SPR_IDX1      (1)
+#define CMDQ_THR_SPR_IDX2      (2)
+#define CMDQ_THR_SPR_IDX3      (3)
+
 struct cmdq_pkt;
 
 struct cmdq_client_reg {
@@ -62,17 +71,19 @@ void cmdq_mbox_destroy(struct cmdq_client *client);
 /**
  * cmdq_pkt_create() - create a CMDQ packet
  * @client:    the CMDQ mailbox client
+ * @pkt:       the CMDQ packet
  * @size:      required CMDQ buffer size
  *
- * Return: CMDQ packet pointer
+ * Return: 0 for success; else the error code is returned
  */
-struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size);
+int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size);
 
 /**
  * cmdq_pkt_destroy() - destroy the CMDQ packet
+ * @client:    the CMDQ mailbox client
  * @pkt:       the CMDQ packet
  */
-void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
+void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt);
 
 /**
  * cmdq_pkt_write() - append write command to the CMDQ packet
@@ -173,6 +184,18 @@ int cmdq_pkt_write_s_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
 int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
                                u16 addr_low, u32 value, u32 mask);
 
+/**
+ * cmdq_pkt_mem_move() - append memory move command to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @src_addr:  source address
+ * @dst_addr:  destination address
+ *
+ * Appends a CMDQ command to copy the value found in `src_addr` to `dst_addr`.
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_mem_move(struct cmdq_pkt *pkt, dma_addr_t src_addr, dma_addr_t dst_addr);
+
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
  * @pkt:       the CMDQ packet
@@ -183,6 +206,21 @@ int cmdq_pkt_write_s_mask_value(struct cmdq_pkt *pkt, u8 high_addr_reg_idx,
  */
 int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event, bool clear);
 
+/**
+ * cmdq_pkt_acquire_event() - append acquire event command to the CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @event:     the desired event to be acquired
+ *
+ * User can use cmdq_pkt_acquire_event() as `mutex_lock` and cmdq_pkt_clear_event()
+ * as `mutex_unlock` to protect some `critical section` instructions between them.
+ * cmdq_pkt_acquire_event() would wait for event to be cleared.
+ * After event is cleared by cmdq_pkt_clear_event in other GCE threads,
+ * cmdq_pkt_acquire_event() would set event and keep executing next instruction.
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_acquire_event(struct cmdq_pkt *pkt, u16 event);
+
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
  * @pkt:       the CMDQ packet
@@ -248,36 +286,76 @@ int cmdq_pkt_poll_mask(struct cmdq_pkt *pkt, u8 subsys,
 int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value);
 
 /**
- * cmdq_pkt_jump() - Append jump command to the CMDQ packet, ask GCE
- *                  to execute an instruction that change current thread PC to
- *                  a physical address which should contains more instruction.
+ * cmdq_pkt_poll_addr() - Append blocking POLL command to CMDQ packet
+ * @pkt:       the CMDQ packet
+ * @addr:      the hardware register address
+ * @value:     the specified target register value
+ * @mask:      the specified target register mask
+ *
+ * Appends a polling (POLL) command to the CMDQ packet and asks the GCE
+ * to execute an instruction that checks for the specified `value` (with
+ * or without `mask`) to appear in the specified hardware register `addr`.
+ * All GCE threads will be blocked by this instruction.
+ *
+ * Return: 0 for success or negative error code
+ */
+int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask);
+
+/**
+ * cmdq_pkt_jump_abs() - Append jump command to the CMDQ packet, ask GCE
+ *                      to execute an instruction that change current thread
+ *                      PC to a absolute physical address which should
+ *                      contains more instruction.
  * @pkt:        the CMDQ packet
- * @addr:       physical address of target instruction buffer
+ * @addr:       absolute physical address of target instruction buffer
+ * @shift_pa:  shift bits of physical address in CMDQ instruction. This value
+ *             is got by cmdq_get_shift_pa().
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
+int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa);
+
+/* This wrapper has to be removed after all users migrated to jump_abs */
+static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
+{
+       return cmdq_pkt_jump_abs(pkt, addr, shift_pa);
+}
 
 /**
- * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
+ * cmdq_pkt_jump_rel() - Append jump command to the CMDQ packet, ask GCE
+ *                      to execute an instruction that change current thread
+ *                      PC to a physical address with relative offset. The
+ *                      target address should contains more instruction.
  * @pkt:       the CMDQ packet
+ * @offset:    relative offset of target instruction buffer from current PC.
+ * @shift_pa:  shift bits of physical address in CMDQ instruction. This value
+ *             is got by cmdq_get_shift_pa().
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
+int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa);
+
+/**
+ * cmdq_pkt_eoc() - Append EOC and ask GCE to generate an IRQ at end of execution
+ * @pkt:       The CMDQ packet
+ *
+ * Appends an End Of Code (EOC) command to the CMDQ packet and asks the GCE
+ * to generate an interrupt at the end of the execution of all commands in
+ * the pipeline.
+ * The EOC command is usually appended to the end of the pipeline to notify
+ * that all commands are done.
+ *
+ * Return: 0 for success or negative error number
+ */
+int cmdq_pkt_eoc(struct cmdq_pkt *pkt);
 
 /**
- * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
- *                          packet and call back at the end of done packet
+ * cmdq_pkt_finalize() - Append EOC and jump command to pkt.
  * @pkt:       the CMDQ packet
  *
  * Return: 0 for success; else the error code is returned
- *
- * Trigger CMDQ to asynchronously execute the CMDQ packet and call back
- * at the end of done packet. Note that this is an ASYNC function. When the
- * function returned, it may or may not be finished.
  */
-int cmdq_pkt_flush_async(struct cmdq_pkt *pkt);
+int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
 
 #else /* IS_ENABLED(CONFIG_MTK_CMDQ) */
 
@@ -294,12 +372,12 @@ static inline struct cmdq_client *cmdq_mbox_create(struct device *dev, int index
 
 static inline void cmdq_mbox_destroy(struct cmdq_client *client) { }
 
-static inline  struct cmdq_pkt *cmdq_pkt_create(struct cmdq_client *client, size_t size)
+static inline int cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt, size_t size)
 {
-       return ERR_PTR(-EINVAL);
+       return -EINVAL;
 }
 
-static inline void cmdq_pkt_destroy(struct cmdq_pkt *pkt) { }
+static inline void cmdq_pkt_destroy(struct cmdq_client *client, struct cmdq_pkt *pkt) { }
 
 static inline int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 {
@@ -374,17 +452,32 @@ static inline int cmdq_pkt_assign(struct cmdq_pkt *pkt, u16 reg_idx, u32 value)
        return -EINVAL;
 }
 
-static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr)
+static inline int cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, dma_addr_t addr, u32 value, u32 mask)
 {
        return -EINVAL;
 }
 
-static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
+static inline int cmdq_pkt_jump_abs(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
+{
+       return -EINVAL;
+}
+
+static inline int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr, u8 shift_pa)
+{
+       return -EINVAL;
+}
+
+static inline int cmdq_pkt_jump_rel(struct cmdq_pkt *pkt, s32 offset, u8 shift_pa)
 {
        return -EINVAL;
 }
 
-static inline int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
+static inline int cmdq_pkt_eoc(struct cmdq_pkt *pkt)
+{
+       return -EINVAL;
+}
+
+static inline int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
 {
        return -EINVAL;
 }
index 447133171d95fd859e5a16afa8ab4cf6104c3dbd..4d96bbdb45f086932cb595ce60814832e5aac3f2 100644 (file)
@@ -64,8 +64,10 @@ static inline int __srcu_read_lock(struct srcu_struct *ssp)
 {
        int idx;
 
+       preempt_disable();  // Needed for PREEMPT_AUTO
        idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;
        WRITE_ONCE(ssp->srcu_lock_nesting[idx], READ_ONCE(ssp->srcu_lock_nesting[idx]) + 1);
+       preempt_enable();
        return idx;
 }
 
index 52150570d37a53f79767770308e0745e642c9970..bf92441dbad2841993a8ef2db1dd2b8b70f2c919 100644 (file)
@@ -53,6 +53,7 @@ struct kstat {
        u32             dio_mem_align;
        u32             dio_offset_align;
        u64             change_cookie;
+       u64             subvol;
 };
 
 /* These definitions are internal to the kernel for now. Mainly used by nfsd. */
diff --git a/include/linux/tee_core.h b/include/linux/tee_core.h
new file mode 100644 (file)
index 0000000..efd16ed
--- /dev/null
@@ -0,0 +1,306 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 Linaro Limited
+ */
+
+#ifndef __TEE_CORE_H
+#define __TEE_CORE_H
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/idr.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/tee.h>
+#include <linux/tee_drv.h>
+#include <linux/types.h>
+#include <linux/uuid.h>
+
+/*
+ * The file describes the API provided by the generic TEE driver to the
+ * specific TEE driver.
+ */
+
+#define TEE_SHM_DYNAMIC                BIT(0)  /* Dynamic shared memory registered */
+                                       /* in secure world */
+#define TEE_SHM_USER_MAPPED    BIT(1)  /* Memory mapped in user space */
+#define TEE_SHM_POOL           BIT(2)  /* Memory allocated from pool */
+#define TEE_SHM_PRIV           BIT(3)  /* Memory private to TEE driver */
+
+#define TEE_DEVICE_FLAG_REGISTERED     0x1
+#define TEE_MAX_DEV_NAME_LEN           32
+
+/**
+ * struct tee_device - TEE Device representation
+ * @name:      name of device
+ * @desc:      description of device
+ * @id:                unique id of device
+ * @flags:     represented by TEE_DEVICE_FLAG_REGISTERED above
+ * @dev:       embedded basic device structure
+ * @cdev:      embedded cdev
+ * @num_users: number of active users of this device
+ * @c_no_user: completion used when unregistering the device
+ * @mutex:     mutex protecting @num_users and @idr
+ * @idr:       register of user space shared memory objects allocated or
+ *             registered on this device
+ * @pool:      shared memory pool
+ */
+struct tee_device {
+       char name[TEE_MAX_DEV_NAME_LEN];
+       const struct tee_desc *desc;
+       int id;
+       unsigned int flags;
+
+       struct device dev;
+       struct cdev cdev;
+
+       size_t num_users;
+       struct completion c_no_users;
+       struct mutex mutex;     /* protects num_users and idr */
+
+       struct idr idr;
+       struct tee_shm_pool *pool;
+};
+
+/**
+ * struct tee_driver_ops - driver operations vtable
+ * @get_version:       returns version of driver
+ * @open:              called when the device file is opened
+ * @release:           release this open file
+ * @open_session:      open a new session
+ * @close_session:     close a session
+ * @system_session:    declare session as a system session
+ * @invoke_func:       invoke a trusted function
+ * @cancel_req:                request cancel of an ongoing invoke or open
+ * @supp_recv:         called for supplicant to get a command
+ * @supp_send:         called for supplicant to send a response
+ * @shm_register:      register shared memory buffer in TEE
+ * @shm_unregister:    unregister shared memory buffer in TEE
+ */
+struct tee_driver_ops {
+       void (*get_version)(struct tee_device *teedev,
+                           struct tee_ioctl_version_data *vers);
+       int (*open)(struct tee_context *ctx);
+       void (*release)(struct tee_context *ctx);
+       int (*open_session)(struct tee_context *ctx,
+                           struct tee_ioctl_open_session_arg *arg,
+                           struct tee_param *param);
+       int (*close_session)(struct tee_context *ctx, u32 session);
+       int (*system_session)(struct tee_context *ctx, u32 session);
+       int (*invoke_func)(struct tee_context *ctx,
+                          struct tee_ioctl_invoke_arg *arg,
+                          struct tee_param *param);
+       int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
+       int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
+                        struct tee_param *param);
+       int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params,
+                        struct tee_param *param);
+       int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm,
+                           struct page **pages, size_t num_pages,
+                           unsigned long start);
+       int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
+};
+
+/**
+ * struct tee_desc - Describes the TEE driver to the subsystem
+ * @name:      name of driver
+ * @ops:       driver operations vtable
+ * @owner:     module providing the driver
+ * @flags:     Extra properties of driver, defined by TEE_DESC_* below
+ */
+#define TEE_DESC_PRIVILEGED    0x1
+struct tee_desc {
+       const char *name;
+       const struct tee_driver_ops *ops;
+       struct module *owner;
+       u32 flags;
+};
+
+/**
+ * tee_device_alloc() - Allocate a new struct tee_device instance
+ * @teedesc:   Descriptor for this driver
+ * @dev:       Parent device for this device
+ * @pool:      Shared memory pool, NULL if not used
+ * @driver_data: Private driver data for this device
+ *
+ * Allocates a new struct tee_device instance. The device is
+ * removed by tee_device_unregister().
+ *
+ * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
+ */
+struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
+                                   struct device *dev,
+                                   struct tee_shm_pool *pool,
+                                   void *driver_data);
+
+/**
+ * tee_device_register() - Registers a TEE device
+ * @teedev:    Device to register
+ *
+ * tee_device_unregister() need to be called to remove the @teedev if
+ * this function fails.
+ *
+ * @returns < 0 on failure
+ */
+int tee_device_register(struct tee_device *teedev);
+
+/**
+ * tee_device_unregister() - Removes a TEE device
+ * @teedev:    Device to unregister
+ *
+ * This function should be called to remove the @teedev even if
+ * tee_device_register() hasn't been called yet. Does nothing if
+ * @teedev is NULL.
+ */
+void tee_device_unregister(struct tee_device *teedev);
+
+/**
+ * tee_session_calc_client_uuid() - Calculates client UUID for session
+ * @uuid:              Resulting UUID
+ * @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
+ * @connectuon_data:   Connection data for opening session
+ *
+ * Based on connection method calculates UUIDv5 based client UUID.
+ *
+ * For group based logins verifies that calling process has specified
+ * credentials.
+ *
+ * @return < 0 on failure
+ */
+int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
+                                const u8 connection_data[TEE_IOCTL_UUID_LEN]);
+
+/**
+ * struct tee_shm_pool - shared memory pool
+ * @ops:               operations
+ * @private_data:      private data for the shared memory manager
+ */
+struct tee_shm_pool {
+       const struct tee_shm_pool_ops *ops;
+       void *private_data;
+};
+
+/**
+ * struct tee_shm_pool_ops - shared memory pool operations
+ * @alloc:             called when allocating shared memory
+ * @free:              called when freeing shared memory
+ * @destroy_pool:      called when destroying the pool
+ */
+struct tee_shm_pool_ops {
+       int (*alloc)(struct tee_shm_pool *pool, struct tee_shm *shm,
+                    size_t size, size_t align);
+       void (*free)(struct tee_shm_pool *pool, struct tee_shm *shm);
+       void (*destroy_pool)(struct tee_shm_pool *pool);
+};
+
+/*
+ * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory
+ * @vaddr:     Virtual address of start of pool
+ * @paddr:     Physical address of start of pool
+ * @size:      Size in bytes of the pool
+ *
+ * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
+ */
+struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
+                                               phys_addr_t paddr, size_t size,
+                                               int min_alloc_order);
+
+/**
+ * tee_shm_pool_free() - Free a shared memory pool
+ * @pool:      The shared memory pool to free
+ *
+ * The must be no remaining shared memory allocated from this pool when
+ * this function is called.
+ */
+static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
+{
+       pool->ops->destroy_pool(pool);
+}
+
+/**
+ * tee_get_drvdata() - Return driver_data pointer
+ * @returns the driver_data pointer supplied to tee_register().
+ */
+void *tee_get_drvdata(struct tee_device *teedev);
+
+/**
+ * tee_shm_alloc_priv_buf() - Allocate shared memory for private use by specific
+ *                            TEE driver
+ * @ctx:       The TEE context for shared memory allocation
+ * @size:      Shared memory allocation size
+ * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
+ */
+struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
+
+int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align,
+                            int (*shm_register)(struct tee_context *ctx,
+                                                struct tee_shm *shm,
+                                                struct page **pages,
+                                                size_t num_pages,
+                                                unsigned long start));
+void tee_dyn_shm_free_helper(struct tee_shm *shm,
+                            int (*shm_unregister)(struct tee_context *ctx,
+                                                  struct tee_shm *shm));
+
+/**
+ * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
+ * @shm:       Shared memory handle
+ * @returns true if object is dynamic shared memory
+ */
+static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
+{
+       return shm && (shm->flags & TEE_SHM_DYNAMIC);
+}
+
+/**
+ * tee_shm_put() - Decrease reference count on a shared memory handle
+ * @shm:       Shared memory handle
+ */
+void tee_shm_put(struct tee_shm *shm);
+
+/**
+ * tee_shm_get_id() - Get id of a shared memory object
+ * @shm:       Shared memory handle
+ * @returns id
+ */
+static inline int tee_shm_get_id(struct tee_shm *shm)
+{
+       return shm->id;
+}
+
+/**
+ * tee_shm_get_from_id() - Find shared memory object and increase reference
+ * count
+ * @ctx:       Context owning the shared memory
+ * @id:                Id of shared memory object
+ * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
+ */
+struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
+
+static inline bool tee_param_is_memref(struct tee_param *param)
+{
+       switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
+       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+               return true;
+       default:
+               return false;
+       }
+}
+
+/**
+ * teedev_open() - Open a struct tee_device
+ * @teedev:    Device to open
+ *
+ * @return a pointer to struct tee_context on success or an ERR_PTR on failure.
+ */
+struct tee_context *teedev_open(struct tee_device *teedev);
+
+/**
+ * teedev_close_context() - closes a struct tee_context
+ * @ctx:       The struct tee_context to close
+ */
+void teedev_close_context(struct tee_context *ctx);
+
+#endif /*__TEE_CORE_H*/
index 71632e3c5f18fb9d564542c8e6d7984eb54f5151..786b9ae6cf4d5cef359f8e88b863621632f2ef0f 100644 (file)
@@ -1,40 +1,28 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2022 Linaro Limited
+ * Copyright (c) 2015-2024 Linaro Limited
  */
 
 #ifndef __TEE_DRV_H
 #define __TEE_DRV_H
 
 #include <linux/device.h>
-#include <linux/idr.h>
 #include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/mod_devicetable.h>
 #include <linux/tee.h>
 #include <linux/types.h>
-#include <linux/uuid.h>
 
 /*
- * The file describes the API provided by the generic TEE driver to the
- * specific TEE driver.
+ * The file describes the API provided by the TEE subsystem to the
+ * TEE client drivers.
  */
 
-#define TEE_SHM_DYNAMIC                BIT(0)  /* Dynamic shared memory registered */
-                                       /* in secure world */
-#define TEE_SHM_USER_MAPPED    BIT(1)  /* Memory mapped in user space */
-#define TEE_SHM_POOL           BIT(2)  /* Memory allocated from pool */
-#define TEE_SHM_PRIV           BIT(3)  /* Memory private to TEE driver */
-
-struct device;
 struct tee_device;
-struct tee_shm;
-struct tee_shm_pool;
 
 /**
  * struct tee_context - driver specific context on file pointer data
  * @teedev:    pointer to this drivers struct tee_device
- * @list_shm:  List of shared memory object owned by this context
  * @data:      driver specific context data, managed by the driver
  * @refcount:  reference counter for this structure
  * @releasing:  flag that indicates if context is being released right now.
@@ -57,134 +45,6 @@ struct tee_context {
        bool cap_memref_null;
 };
 
-struct tee_param_memref {
-       size_t shm_offs;
-       size_t size;
-       struct tee_shm *shm;
-};
-
-struct tee_param_value {
-       u64 a;
-       u64 b;
-       u64 c;
-};
-
-struct tee_param {
-       u64 attr;
-       union {
-               struct tee_param_memref memref;
-               struct tee_param_value value;
-       } u;
-};
-
-/**
- * struct tee_driver_ops - driver operations vtable
- * @get_version:       returns version of driver
- * @open:              called when the device file is opened
- * @release:           release this open file
- * @open_session:      open a new session
- * @close_session:     close a session
- * @system_session:    declare session as a system session
- * @invoke_func:       invoke a trusted function
- * @cancel_req:                request cancel of an ongoing invoke or open
- * @supp_recv:         called for supplicant to get a command
- * @supp_send:         called for supplicant to send a response
- * @shm_register:      register shared memory buffer in TEE
- * @shm_unregister:    unregister shared memory buffer in TEE
- */
-struct tee_driver_ops {
-       void (*get_version)(struct tee_device *teedev,
-                           struct tee_ioctl_version_data *vers);
-       int (*open)(struct tee_context *ctx);
-       void (*release)(struct tee_context *ctx);
-       int (*open_session)(struct tee_context *ctx,
-                           struct tee_ioctl_open_session_arg *arg,
-                           struct tee_param *param);
-       int (*close_session)(struct tee_context *ctx, u32 session);
-       int (*system_session)(struct tee_context *ctx, u32 session);
-       int (*invoke_func)(struct tee_context *ctx,
-                          struct tee_ioctl_invoke_arg *arg,
-                          struct tee_param *param);
-       int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
-       int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
-                        struct tee_param *param);
-       int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params,
-                        struct tee_param *param);
-       int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm,
-                           struct page **pages, size_t num_pages,
-                           unsigned long start);
-       int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm);
-};
-
-/**
- * struct tee_desc - Describes the TEE driver to the subsystem
- * @name:      name of driver
- * @ops:       driver operations vtable
- * @owner:     module providing the driver
- * @flags:     Extra properties of driver, defined by TEE_DESC_* below
- */
-#define TEE_DESC_PRIVILEGED    0x1
-struct tee_desc {
-       const char *name;
-       const struct tee_driver_ops *ops;
-       struct module *owner;
-       u32 flags;
-};
-
-/**
- * tee_device_alloc() - Allocate a new struct tee_device instance
- * @teedesc:   Descriptor for this driver
- * @dev:       Parent device for this device
- * @pool:      Shared memory pool, NULL if not used
- * @driver_data: Private driver data for this device
- *
- * Allocates a new struct tee_device instance. The device is
- * removed by tee_device_unregister().
- *
- * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
- */
-struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
-                                   struct device *dev,
-                                   struct tee_shm_pool *pool,
-                                   void *driver_data);
-
-/**
- * tee_device_register() - Registers a TEE device
- * @teedev:    Device to register
- *
- * tee_device_unregister() need to be called to remove the @teedev if
- * this function fails.
- *
- * @returns < 0 on failure
- */
-int tee_device_register(struct tee_device *teedev);
-
-/**
- * tee_device_unregister() - Removes a TEE device
- * @teedev:    Device to unregister
- *
- * This function should be called to remove the @teedev even if
- * tee_device_register() hasn't been called yet. Does nothing if
- * @teedev is NULL.
- */
-void tee_device_unregister(struct tee_device *teedev);
-
-/**
- * tee_session_calc_client_uuid() - Calculates client UUID for session
- * @uuid:              Resulting UUID
- * @connection_method: Connection method for session (TEE_IOCTL_LOGIN_*)
- * @connectuon_data:   Connection data for opening session
- *
- * Based on connection method calculates UUIDv5 based client UUID.
- *
- * For group based logins verifies that calling process has specified
- * credentials.
- *
- * @return < 0 on failure
- */
-int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
-                                const u8 connection_data[TEE_IOCTL_UUID_LEN]);
-
 /**
  * struct tee_shm - shared memory object
  * @ctx:       context using the object
@@ -195,15 +55,12 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method,
  * @pages:     locked pages from userspace
  * @num_pages: number of locked pages
  * @refcount:  reference counter
- * @flags:     defined by TEE_SHM_* in tee_drv.h
+ * @flags:     defined by TEE_SHM_* in tee_core.h
  * @id:                unique id of a shared memory object on this device, shared
  *             with user space
  * @sec_world_id:
  *             secure world assigned id of this shared memory object, not
  *             used by all drivers
- *
- * This pool is only supposed to be accessed directly from the TEE
- * subsystem and from drivers that implements their own shm pool manager.
  */
 struct tee_shm {
        struct tee_context *ctx;
@@ -219,87 +76,52 @@ struct tee_shm {
        u64 sec_world_id;
 };
 
-/**
- * struct tee_shm_pool - shared memory pool
- * @ops:               operations
- * @private_data:      private data for the shared memory manager
- */
-struct tee_shm_pool {
-       const struct tee_shm_pool_ops *ops;
-       void *private_data;
+struct tee_param_memref {
+       size_t shm_offs;
+       size_t size;
+       struct tee_shm *shm;
 };
 
-/**
- * struct tee_shm_pool_ops - shared memory pool operations
- * @alloc:             called when allocating shared memory
- * @free:              called when freeing shared memory
- * @destroy_pool:      called when destroying the pool
- */
-struct tee_shm_pool_ops {
-       int (*alloc)(struct tee_shm_pool *pool, struct tee_shm *shm,
-                    size_t size, size_t align);
-       void (*free)(struct tee_shm_pool *pool, struct tee_shm *shm);
-       void (*destroy_pool)(struct tee_shm_pool *pool);
+struct tee_param_value {
+       u64 a;
+       u64 b;
+       u64 c;
 };
 
-/*
- * tee_shm_pool_alloc_res_mem() - Create a shm manager for reserved memory
- * @vaddr:     Virtual address of start of pool
- * @paddr:     Physical address of start of pool
- * @size:      Size in bytes of the pool
- *
- * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
- */
-struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr,
-                                               phys_addr_t paddr, size_t size,
-                                               int min_alloc_order);
+struct tee_param {
+       u64 attr;
+       union {
+               struct tee_param_memref memref;
+               struct tee_param_value value;
+       } u;
+};
 
 /**
- * tee_shm_pool_free() - Free a shared memory pool
- * @pool:      The shared memory pool to free
- *
- * The must be no remaining shared memory allocated from this pool when
- * this function is called.
+ * tee_shm_alloc_kernel_buf() - Allocate kernel shared memory for a
+ *                              particular TEE client driver
+ * @ctx:       The TEE context for shared memory allocation
+ * @size:      Shared memory allocation size
+ * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
  */
-static inline void tee_shm_pool_free(struct tee_shm_pool *pool)
-{
-       pool->ops->destroy_pool(pool);
-}
+struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
 
 /**
- * tee_get_drvdata() - Return driver_data pointer
- * @returns the driver_data pointer supplied to tee_register().
+ * tee_shm_register_kernel_buf() - Register kernel shared memory for a
+ *                                 particular TEE client driver
+ * @ctx:       The TEE context for shared memory registration
+ * @addr:      Kernel buffer address
+ * @length:    Kernel buffer length
+ * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
  */
-void *tee_get_drvdata(struct tee_device *teedev);
-
-struct tee_shm *tee_shm_alloc_priv_buf(struct tee_context *ctx, size_t size);
-struct tee_shm *tee_shm_alloc_kernel_buf(struct tee_context *ctx, size_t size);
-
 struct tee_shm *tee_shm_register_kernel_buf(struct tee_context *ctx,
                                            void *addr, size_t length);
 
-/**
- * tee_shm_is_dynamic() - Check if shared memory object is of the dynamic kind
- * @shm:       Shared memory handle
- * @returns true if object is dynamic shared memory
- */
-static inline bool tee_shm_is_dynamic(struct tee_shm *shm)
-{
-       return shm && (shm->flags & TEE_SHM_DYNAMIC);
-}
-
 /**
  * tee_shm_free() - Free shared memory
  * @shm:       Handle to shared memory to free
  */
 void tee_shm_free(struct tee_shm *shm);
 
-/**
- * tee_shm_put() - Decrease reference count on a shared memory handle
- * @shm:       Shared memory handle
- */
-void tee_shm_put(struct tee_shm *shm);
-
 /**
  * tee_shm_get_va() - Get virtual address of a shared memory plus an offset
  * @shm:       Shared memory handle
@@ -352,25 +174,6 @@ static inline size_t tee_shm_get_page_offset(struct tee_shm *shm)
        return shm->offset;
 }
 
-/**
- * tee_shm_get_id() - Get id of a shared memory object
- * @shm:       Shared memory handle
- * @returns id
- */
-static inline int tee_shm_get_id(struct tee_shm *shm)
-{
-       return shm->id;
-}
-
-/**
- * tee_shm_get_from_id() - Find shared memory object and increase reference
- * count
- * @ctx:       Context owning the shared memory
- * @id:                Id of shared memory object
- * @returns a pointer to 'struct tee_shm' on success or an ERR_PTR on failure
- */
-struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id);
-
 /**
  * tee_client_open_context() - Open a TEE context
  * @start:     if not NULL, continue search after this context
@@ -470,18 +273,6 @@ int tee_client_invoke_func(struct tee_context *ctx,
 int tee_client_cancel_req(struct tee_context *ctx,
                          struct tee_ioctl_cancel_arg *arg);
 
-static inline bool tee_param_is_memref(struct tee_param *param)
-{
-       switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
-       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
-       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
-       case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
-               return true;
-       default:
-               return false;
-       }
-}
-
 extern const struct bus_type tee_bus_type;
 
 /**
@@ -509,18 +300,4 @@ struct tee_client_driver {
 #define to_tee_client_driver(d) \
                container_of(d, struct tee_client_driver, driver)
 
-/**
- * teedev_open() - Open a struct tee_device
- * @teedev:    Device to open
- *
- * @return a pointer to struct tee_context on success or an ERR_PTR on failure.
- */
-struct tee_context *teedev_open(struct tee_device *teedev);
-
-/**
- * teedev_close_context() - closes a struct tee_context
- * @ctx:       The struct tee_context to close
- */
-void teedev_close_context(struct tee_context *ctx);
-
 #endif /*__TEE_DRV_H*/
index 4ee9d13749adc1ae0a6bd47136694c280ca943ae..c17e4efbb2e5cd367f880fec4c7e263517e631ed 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/fs.h>
 #include <linux/highmem.h>
 #include <crypto/hash_info.h>
+#include <crypto/aes.h>
 
 #define TPM_DIGEST_SIZE 20     /* Max TPM v1.2 PCR size */
 #define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
 struct tpm_chip;
 struct trusted_key_payload;
 struct trusted_key_options;
+/* opaque structure, holds auth session parameters like the session key */
+struct tpm2_auth;
+
+enum tpm2_session_types {
+       TPM2_SE_HMAC    = 0x00,
+       TPM2_SE_POLICY  = 0x01,
+       TPM2_SE_TRIAL   = 0x02,
+};
 
 /* if you add a new hash to this, increment TPM_MAX_HASHES below */
 enum tpm_algorithms {
        TPM_ALG_ERROR           = 0x0000,
        TPM_ALG_SHA1            = 0x0004,
+       TPM_ALG_AES             = 0x0006,
        TPM_ALG_KEYEDHASH       = 0x0008,
        TPM_ALG_SHA256          = 0x000B,
        TPM_ALG_SHA384          = 0x000C,
        TPM_ALG_SHA512          = 0x000D,
        TPM_ALG_NULL            = 0x0010,
        TPM_ALG_SM3_256         = 0x0012,
+       TPM_ALG_ECC             = 0x0023,
+       TPM_ALG_CFB             = 0x0043,
 };
 
 /*
@@ -49,6 +61,11 @@ enum tpm_algorithms {
  */
 #define TPM_MAX_HASHES 5
 
+enum tpm2_curves {
+       TPM2_ECC_NONE           = 0x0000,
+       TPM2_ECC_NIST_P256      = 0x0003,
+};
+
 struct tpm_digest {
        u16 alg_id;
        u8 digest[TPM_MAX_DIGEST_SIZE];
@@ -116,6 +133,20 @@ struct tpm_chip_seqops {
        const struct seq_operations *seqops;
 };
 
+/* fixed define for the curve we use which is NIST_P256 */
+#define EC_PT_SZ       32
+
+/*
+ * fixed define for the size of a name.  This is actually HASHALG size
+ * plus 2, so 32 for SHA256
+ */
+#define TPM2_NAME_SIZE 34
+
+/*
+ * The maximum size for an object context
+ */
+#define TPM2_MAX_CONTEXT_SIZE 4096
+
 struct tpm_chip {
        struct device dev;
        struct device devs;
@@ -170,6 +201,18 @@ struct tpm_chip {
 
        /* active locality */
        int locality;
+
+#ifdef CONFIG_TCG_TPM2_HMAC
+       /* details for communication security via sessions */
+
+       /* saved context for NULL seed */
+       u8 null_key_context[TPM2_MAX_CONTEXT_SIZE];
+        /* name of NULL seed */
+       u8 null_key_name[TPM2_NAME_SIZE];
+       u8 null_ec_key_x[EC_PT_SZ];
+       u8 null_ec_key_y[EC_PT_SZ];
+       struct tpm2_auth *auth;
+#endif
 };
 
 #define TPM_HEADER_SIZE                10
@@ -194,6 +237,7 @@ enum tpm2_timeouts {
 enum tpm2_structures {
        TPM2_ST_NO_SESSIONS     = 0x8001,
        TPM2_ST_SESSIONS        = 0x8002,
+       TPM2_ST_CREATION        = 0x8021,
 };
 
 /* Indicates from what layer of the software stack the error comes from */
@@ -204,6 +248,7 @@ enum tpm2_return_codes {
        TPM2_RC_SUCCESS         = 0x0000,
        TPM2_RC_HASH            = 0x0083, /* RC_FMT1 */
        TPM2_RC_HANDLE          = 0x008B,
+       TPM2_RC_INTEGRITY       = 0x009F,
        TPM2_RC_INITIALIZE      = 0x0100, /* RC_VER1 */
        TPM2_RC_FAILURE         = 0x0101,
        TPM2_RC_DISABLED        = 0x0120,
@@ -231,6 +276,8 @@ enum tpm2_command_codes {
        TPM2_CC_CONTEXT_LOAD            = 0x0161,
        TPM2_CC_CONTEXT_SAVE            = 0x0162,
        TPM2_CC_FLUSH_CONTEXT           = 0x0165,
+       TPM2_CC_READ_PUBLIC             = 0x0173,
+       TPM2_CC_START_AUTH_SESS         = 0x0176,
        TPM2_CC_VERIFY_SIGNATURE        = 0x0177,
        TPM2_CC_GET_CAPABILITY          = 0x017A,
        TPM2_CC_GET_RANDOM              = 0x017B,
@@ -243,9 +290,25 @@ enum tpm2_command_codes {
 };
 
 enum tpm2_permanent_handles {
+       TPM2_RH_NULL            = 0x40000007,
        TPM2_RS_PW              = 0x40000009,
 };
 
+/* Most Significant Octet for key types  */
+enum tpm2_mso_type {
+       TPM2_MSO_NVRAM          = 0x01,
+       TPM2_MSO_SESSION        = 0x02,
+       TPM2_MSO_POLICY         = 0x03,
+       TPM2_MSO_PERMANENT      = 0x40,
+       TPM2_MSO_VOLATILE       = 0x80,
+       TPM2_MSO_PERSISTENT     = 0x81,
+};
+
+static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
+{
+       return handle >> 24;
+}
+
 enum tpm2_capabilities {
        TPM2_CAP_HANDLES        = 1,
        TPM2_CAP_COMMANDS       = 2,
@@ -284,6 +347,7 @@ enum tpm_chip_flags {
        TPM_CHIP_FLAG_FIRMWARE_UPGRADE          = BIT(7),
        TPM_CHIP_FLAG_SUSPENDED                 = BIT(8),
        TPM_CHIP_FLAG_HWRNG_DISABLED            = BIT(9),
+       TPM_CHIP_FLAG_DISABLE                   = BIT(10),
 };
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
@@ -297,28 +361,61 @@ struct tpm_header {
        };
 } __packed;
 
-/* A string buffer type for constructing TPM commands. This is based on the
- * ideas of string buffer code in security/keys/trusted.h but is heap based
- * in order to keep the stack usage minimal.
- */
-
 enum tpm_buf_flags {
+       /* the capacity exceeded: */
        TPM_BUF_OVERFLOW        = BIT(0),
+       /* TPM2B format: */
+       TPM_BUF_TPM2B           = BIT(1),
+       /* read out of boundary: */
+       TPM_BUF_BOUNDARY_ERROR  = BIT(2),
 };
 
+/*
+ * A string buffer type for constructing TPM commands.
+ */
 struct tpm_buf {
-       unsigned int flags;
+       u32 flags;
+       u32 length;
        u8 *data;
+       u8 handles;
 };
 
 enum tpm2_object_attributes {
        TPM2_OA_FIXED_TPM               = BIT(1),
+       TPM2_OA_ST_CLEAR                = BIT(2),
        TPM2_OA_FIXED_PARENT            = BIT(4),
+       TPM2_OA_SENSITIVE_DATA_ORIGIN   = BIT(5),
        TPM2_OA_USER_WITH_AUTH          = BIT(6),
+       TPM2_OA_ADMIN_WITH_POLICY       = BIT(7),
+       TPM2_OA_NO_DA                   = BIT(10),
+       TPM2_OA_ENCRYPTED_DUPLICATION   = BIT(11),
+       TPM2_OA_RESTRICTED              = BIT(16),
+       TPM2_OA_DECRYPT                 = BIT(17),
+       TPM2_OA_SIGN                    = BIT(18),
 };
 
+/*
+ * definitions for the canonical template.  These are mandated
+ * by the TCG key template documents
+ */
+
+#define AES_KEY_BYTES  AES_KEYSIZE_128
+#define AES_KEY_BITS   (AES_KEY_BYTES*8)
+#define TPM2_OA_TMPL   (TPM2_OA_NO_DA |                        \
+                        TPM2_OA_FIXED_TPM |                    \
+                        TPM2_OA_FIXED_PARENT |                 \
+                        TPM2_OA_SENSITIVE_DATA_ORIGIN |        \
+                        TPM2_OA_USER_WITH_AUTH |               \
+                        TPM2_OA_DECRYPT |                      \
+                        TPM2_OA_RESTRICTED)
+
 enum tpm2_session_attributes {
        TPM2_SA_CONTINUE_SESSION        = BIT(0),
+       TPM2_SA_AUDIT_EXCLUSIVE         = BIT(1),
+       TPM2_SA_AUDIT_RESET             = BIT(3),
+       TPM2_SA_DECRYPT                 = BIT(5),
+       TPM2_SA_ENCRYPT                 = BIT(6),
+       TPM2_SA_AUDIT                   = BIT(7),
 };
 
 struct tpm2_hash {
@@ -326,84 +423,21 @@ struct tpm2_hash {
        unsigned int tpm_id;
 };
 
-static inline void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal)
-{
-       struct tpm_header *head = (struct tpm_header *)buf->data;
-
-       head->tag = cpu_to_be16(tag);
-       head->length = cpu_to_be32(sizeof(*head));
-       head->ordinal = cpu_to_be32(ordinal);
-}
-
-static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
-{
-       buf->data = (u8 *)__get_free_page(GFP_KERNEL);
-       if (!buf->data)
-               return -ENOMEM;
-
-       buf->flags = 0;
-       tpm_buf_reset(buf, tag, ordinal);
-       return 0;
-}
-
-static inline void tpm_buf_destroy(struct tpm_buf *buf)
-{
-       free_page((unsigned long)buf->data);
-}
-
-static inline u32 tpm_buf_length(struct tpm_buf *buf)
-{
-       struct tpm_header *head = (struct tpm_header *)buf->data;
-
-       return be32_to_cpu(head->length);
-}
-
-static inline u16 tpm_buf_tag(struct tpm_buf *buf)
-{
-       struct tpm_header *head = (struct tpm_header *)buf->data;
-
-       return be16_to_cpu(head->tag);
-}
-
-static inline void tpm_buf_append(struct tpm_buf *buf,
-                                 const unsigned char *new_data,
-                                 unsigned int new_len)
-{
-       struct tpm_header *head = (struct tpm_header *)buf->data;
-       u32 len = tpm_buf_length(buf);
-
-       /* Return silently if overflow has already happened. */
-       if (buf->flags & TPM_BUF_OVERFLOW)
-               return;
-
-       if ((len + new_len) > PAGE_SIZE) {
-               WARN(1, "tpm_buf: overflow\n");
-               buf->flags |= TPM_BUF_OVERFLOW;
-               return;
-       }
-
-       memcpy(&buf->data[len], new_data, new_len);
-       head->length = cpu_to_be32(len + new_len);
-}
-
-static inline void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value)
-{
-       tpm_buf_append(buf, &value, 1);
-}
-
-static inline void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value)
-{
-       __be16 value2 = cpu_to_be16(value);
-
-       tpm_buf_append(buf, (u8 *) &value2, 2);
-}
-
-static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
-{
-       __be32 value2 = cpu_to_be32(value);
-
-       tpm_buf_append(buf, (u8 *) &value2, 4);
-}
+int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal);
+void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
+int tpm_buf_init_sized(struct tpm_buf *buf);
+void tpm_buf_reset_sized(struct tpm_buf *buf);
+void tpm_buf_destroy(struct tpm_buf *buf);
+u32 tpm_buf_length(struct tpm_buf *buf);
+void tpm_buf_append(struct tpm_buf *buf, const u8 *new_data, u16 new_length);
+void tpm_buf_append_u8(struct tpm_buf *buf, const u8 value);
+void tpm_buf_append_u16(struct tpm_buf *buf, const u16 value);
+void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value);
+u8 tpm_buf_read_u8(struct tpm_buf *buf, off_t *offset);
+u16 tpm_buf_read_u16(struct tpm_buf *buf, off_t *offset);
+u32 tpm_buf_read_u32(struct tpm_buf *buf, off_t *offset);
+
+u8 *tpm_buf_parameters(struct tpm_buf *buf);
 
 /*
  * Check if TPM device is in the firmware upgrade mode.
@@ -415,7 +449,7 @@ static inline bool tpm_is_firmware_upgrade(struct tpm_chip *chip)
 
 static inline u32 tpm2_rc_value(u32 rc)
 {
-       return (rc & BIT(7)) ? rc & 0xff : rc;
+       return (rc & BIT(7)) ? rc & 0xbf : rc;
 }
 
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
@@ -429,10 +463,19 @@ extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
                        struct tpm_digest *digest);
 extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
                          struct tpm_digest *digests);
-extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen);
 extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
 extern struct tpm_chip *tpm_default_chip(void);
 void tpm2_flush_context(struct tpm_chip *chip, u32 handle);
+
+static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
+{
+       /* simple authorization for empty auth */
+       tpm_buf_append_u32(buf, 9);             /* total length of auth */
+       tpm_buf_append_u32(buf, handle);
+       tpm_buf_append_u16(buf, 0);             /* nonce len */
+       tpm_buf_append_u8(buf, 0);              /* attributes */
+       tpm_buf_append_u16(buf, 0);             /* hmac len */
+}
 #else
 static inline int tpm_is_tpm2(struct tpm_chip *chip)
 {
@@ -450,10 +493,6 @@ static inline int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
        return -ENODEV;
 }
 
-static inline int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
-{
-       return -ENODEV;
-}
 static inline int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max)
 {
        return -ENODEV;
@@ -463,5 +502,102 @@ static inline struct tpm_chip *tpm_default_chip(void)
 {
        return NULL;
 }
+
+static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
+{
+}
 #endif
+#ifdef CONFIG_TCG_TPM2_HMAC
+
+int tpm2_start_auth_session(struct tpm_chip *chip);
+void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
+                        u32 handle, u8 *name);
+void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
+                                u8 attributes, u8 *passphrase,
+                                int passphraselen);
+static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
+                                                  struct tpm_buf *buf,
+                                                  u8 attributes,
+                                                  u8 *passphrase,
+                                                  int passphraselen)
+{
+       tpm_buf_append_hmac_session(chip, buf, attributes, passphrase,
+                                   passphraselen);
+}
+void tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf);
+int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf,
+                               int rc);
+void tpm2_end_auth_session(struct tpm_chip *chip);
+#else
+#include <asm/unaligned.h>
+
+static inline int tpm2_start_auth_session(struct tpm_chip *chip)
+{
+       return 0;
+}
+static inline void tpm2_end_auth_session(struct tpm_chip *chip)
+{
+}
+static inline void tpm_buf_append_name(struct tpm_chip *chip,
+                                      struct tpm_buf *buf,
+                                      u32 handle, u8 *name)
+{
+       tpm_buf_append_u32(buf, handle);
+       /* count the number of handles in the upper bits of flags */
+       buf->handles++;
+}
+static inline void tpm_buf_append_hmac_session(struct tpm_chip *chip,
+                                              struct tpm_buf *buf,
+                                              u8 attributes, u8 *passphrase,
+                                              int passphraselen)
+{
+       /* offset tells us where the sessions area begins */
+       int offset = buf->handles * 4 + TPM_HEADER_SIZE;
+       u32 len = 9 + passphraselen;
+
+       if (tpm_buf_length(buf) != offset) {
+               /* not the first session so update the existing length */
+               len += get_unaligned_be32(&buf->data[offset]);
+               put_unaligned_be32(len, &buf->data[offset]);
+       } else {
+               tpm_buf_append_u32(buf, len);
+       }
+       /* auth handle */
+       tpm_buf_append_u32(buf, TPM2_RS_PW);
+       /* nonce */
+       tpm_buf_append_u16(buf, 0);
+       /* attributes */
+       tpm_buf_append_u8(buf, 0);
+       /* passphrase */
+       tpm_buf_append_u16(buf, passphraselen);
+       tpm_buf_append(buf, passphrase, passphraselen);
+}
+static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
+                                                  struct tpm_buf *buf,
+                                                  u8 attributes,
+                                                  u8 *passphrase,
+                                                  int passphraselen)
+{
+       int offset = buf->handles * 4 + TPM_HEADER_SIZE;
+       struct tpm_header *head = (struct tpm_header *) buf->data;
+
+       /*
+        * if the only sessions are optional, the command tag
+        * must change to TPM2_ST_NO_SESSIONS
+        */
+       if (tpm_buf_length(buf) == offset)
+               head->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
+}
+static inline void tpm_buf_fill_hmac_session(struct tpm_chip *chip,
+                                            struct tpm_buf *buf)
+{
+}
+static inline int tpm_buf_check_hmac_response(struct tpm_chip *chip,
+                                             struct tpm_buf *buf,
+                                             int rc)
+{
+       return rc;
+}
+#endif /* CONFIG_TCG_TPM2_HMAC */
+
 #endif
index 7a5fe17b6bf9c628bc669d82ad16d7cc9abdb88f..d03f746587167e3c26b19b62f6704f15e96abb66 100644 (file)
@@ -62,6 +62,8 @@ struct eventfs_file;
 typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
                                const struct file_operations **fops);
 
+typedef void (*eventfs_release)(const char *name, void *data);
+
 /**
  * struct eventfs_entry - dynamically created eventfs file call back handler
  * @name:      Then name of the dynamic file in an eventfs directory
@@ -72,6 +74,7 @@ typedef int (*eventfs_callback)(const char *name, umode_t *mode, void **data,
 struct eventfs_entry {
        const char                      *name;
        eventfs_callback                callback;
+       eventfs_release                 release;
 };
 
 struct eventfs_inode;
index 2b2e6f0a54d6e6fc0038ca699b76a8d612eb5a38..2372f9357240d1ec95bc5f887b73f04f58ff29ac 100644 (file)
@@ -145,15 +145,12 @@ struct tty_operations;
  * @count: count of open processes, reaching zero cancels all the work for
  *        this tty and drops a @kref too (but does not free this tty)
  * @winsize: size of the terminal "window" (cf. @winsize_mutex)
- * @flow: flow settings grouped together, see also @flow.unused
+ * @flow: flow settings grouped together
  * @flow.lock: lock for @flow members
  * @flow.stopped: tty stopped/started by stop_tty()/start_tty()
  * @flow.tco_stopped: tty stopped/started by %TCOOFF/%TCOON ioctls (it has
  *                   precedence over @flow.stopped)
- * @flow.unused: alignment for Alpha, so that no members other than @flow.* are
- *              modified by the same 64b word store. The @flow's __aligned is
- *              there for the very same reason.
- * @ctrl: control settings grouped together, see also @ctrl.unused
+ * @ctrl: control settings grouped together
  * @ctrl.lock: lock for @ctrl members
  * @ctrl.pgrp: process group of this tty (setpgrp(2))
  * @ctrl.session: session of this tty (setsid(2)). Writes are protected by both
@@ -161,7 +158,6 @@ struct tty_operations;
  *               them.
  * @ctrl.pktstatus: packet mode status (bitwise OR of %TIOCPKT_ constants)
  * @ctrl.packet: packet mode enabled
- * @ctrl.unused: alignment for Alpha, see @flow.unused for explanation
  * @hw_stopped: not controlled by the tty layer, under @driver's control for CTS
  *             handling
  * @receive_room: bytes permitted to feed to @ldisc without any being lost
@@ -216,8 +212,7 @@ struct tty_struct {
                spinlock_t lock;
                bool stopped;
                bool tco_stopped;
-               unsigned long unused[0];
-       } __aligned(sizeof(unsigned long)) flow;
+       } flow;
 
        struct {
                struct pid *pgrp;
@@ -225,8 +220,7 @@ struct tty_struct {
                spinlock_t lock;
                unsigned char pktstatus;
                bool packet;
-               unsigned long unused[0];
-       } __aligned(sizeof(unsigned long)) ctrl;
+       } ctrl;
 
        bool hw_stopped;
        bool closing;
index 00cebe2b70de7ef3d74c814d4c59b4539c3d55da..7020adedfa08cf1c551bf6396b47830b65946368 100644 (file)
@@ -205,6 +205,16 @@ size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
        return 0;
 }
 
+static __always_inline __must_check
+bool copy_to_iter_full(const void *addr, size_t bytes, struct iov_iter *i)
+{
+       size_t copied = copy_to_iter(addr, bytes, i);
+       if (likely(copied == bytes))
+               return true;
+       iov_iter_revert(i, copied);
+       return false;
+}
+
 static __always_inline __must_check
 bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
 {
index 78ebcf782ce57d5b24e018679b925ae00c42eb94..4f785098c67a1402a3377c9abb67d2be1bb23d04 100644 (file)
@@ -207,6 +207,8 @@ int p9_client_read(struct p9_fid *fid, u64 offset, struct iov_iter *to, int *err
 int p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to,
                int *err);
 int p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err);
+struct netfs_io_subrequest;
+void p9_client_write_subreq(struct netfs_io_subrequest *subreq);
 int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset);
 int p9dirent_read(struct p9_client *clnt, char *buf, int len,
                  struct p9_dirent *dirent);
index 50f1e403dbbb3805277d74ff80b504677e9a7aa0..c1d4ca0463a178736d2416e172784e35e333e126 100644 (file)
@@ -87,6 +87,15 @@ struct napi_gro_cb {
 
        /* used to support CHECKSUM_COMPLETE for tunneling protocols */
        __wsum  csum;
+
+       /* L3 offsets */
+       union {
+               struct {
+                       u16 network_offset;
+                       u16 inner_network_offset;
+               };
+               u16 network_offsets[2];
+       };
 };
 
 #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
index 488a6d2babccf26edfbaecc525f25e03d86b7d62..c4e05b14b648a4a98b67a8da5ed1e29f2413f35c 100644 (file)
@@ -379,14 +379,7 @@ static inline bool udp_skb_is_linear(struct sk_buff *skb)
 static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
                                  struct iov_iter *to)
 {
-       int n;
-
-       n = copy_to_iter(skb->data + off, len, to);
-       if (n == len)
-               return 0;
-
-       iov_iter_revert(to, n);
-       return -EFAULT;
+       return copy_to_iter_full(skb->data + off, len, to) ? 0 : -EFAULT;
 }
 
 /*
index 57c743b7e4fef1146ff49d23b38f54c0c7b99c1a..cb4841a9fffd271315dfe0df9890f50a69b8b055 100644 (file)
@@ -1049,6 +1049,9 @@ struct xfrm_offload {
 #define CRYPTO_INVALID_PACKET_SYNTAX           64
 #define CRYPTO_INVALID_PROTOCOL                        128
 
+       /* Used to keep whole l2 header for transport mode GRO */
+       __u32                   orig_mac_len;
+
        __u8                    proto;
        __u8                    inner_ipproto;
 };
diff --git a/include/soc/fsl/dcp.h b/include/soc/fsl/dcp.h
new file mode 100644 (file)
index 0000000..3ec335d
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 sigma star gmbh
+ *
+ * Specifies paes key slot handles for NXP's DCP (Data Co-Processor) to be used
+ * with the crypto_skcipher_setkey().
+ */
+
+#ifndef MXS_DCP_H
+#define MXS_DCP_H
+
+#define DCP_PAES_KEYSIZE 1
+#define DCP_PAES_KEY_SLOT0 0x00
+#define DCP_PAES_KEY_SLOT1 0x01
+#define DCP_PAES_KEY_SLOT2 0x02
+#define DCP_PAES_KEY_SLOT3 0x03
+#define DCP_PAES_KEY_UNIQUE 0xfe
+#define DCP_PAES_KEY_OTP 0xff
+
+#endif /* MXS_DCP_H */
index c8bb56e6852a8cfbe6ff9a3cd34742827e617397..47a6cab75e630c4c8c4e8caf3fc46d1e1437de1c 100644 (file)
@@ -1,5 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
 
 #ifndef __QCOM_COMMAND_DB_H__
 #define __QCOM_COMMAND_DB_H__
@@ -21,6 +24,8 @@ u32 cmd_db_read_addr(const char *resource_id);
 
 const void *cmd_db_read_aux_data(const char *resource_id, size_t *len);
 
+bool cmd_db_match_resource_addr(u32 addr1, u32 addr2);
+
 enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id);
 
 int cmd_db_ready(void);
@@ -31,6 +36,9 @@ static inline u32 cmd_db_read_addr(const char *resource_id)
 static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len)
 { return ERR_PTR(-ENODEV); }
 
+static inline bool cmd_db_match_resource_addr(u32 addr1, u32 addr2)
+{ return false; }
+
 static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id)
 { return -ENODEV; }
 
index e0629699b56338a76b69616dcc2a79dece2e51f4..1a3c6f66f6205597cb46b3c7cc826802fc35c740 100644 (file)
@@ -267,6 +267,7 @@ struct cs35l56_base {
        bool fw_patched;
        bool secured;
        bool can_hibernate;
+       bool fw_owns_asp1;
        bool cal_data_valid;
        s8 cal_index;
        struct cirrus_amp_cal_data cal_data;
@@ -283,6 +284,7 @@ extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC];
 extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC];
 
 int cs35l56_set_patch(struct cs35l56_base *cs35l56_base);
+int cs35l56_init_asp1_regs_for_driver_control(struct cs35l56_base *cs35l56_base);
 int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base);
 int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command);
 int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base);
index 1af9e68193920d062f3c9cce40eba41dc8d74292..234b5baea69c8e6154c3c048fe002bf99337e245 100644 (file)
@@ -1684,8 +1684,8 @@ struct snd_emu1010 {
        unsigned int clock_fallback;
        unsigned int optical_in; /* 0:SPDIF, 1:ADAT */
        unsigned int optical_out; /* 0:SPDIF, 1:ADAT */
-       struct work_struct firmware_work;
-       struct work_struct clock_work;
+       struct work_struct work;
+       struct mutex lock;
 };
 
 struct snd_emu10k1 {
@@ -1834,6 +1834,9 @@ unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg,
 void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
 int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
 int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
+static inline void snd_emu1010_fpga_lock(struct snd_emu10k1 *emu) { mutex_lock(&emu->emu1010.lock); };
+static inline void snd_emu1010_fpga_unlock(struct snd_emu10k1 *emu) { mutex_unlock(&emu->emu1010.lock); };
+void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value);
 void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value);
 void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value);
 void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src);
index 447a8c21cf57df7d30de48efcd27c435fab2c308..da23484268dfcfd6deeee9b9c40447b034d775fc 100644 (file)
@@ -24,8 +24,8 @@
        E_(netfs_read_trace_write_begin,        "WRITEBEGN")
 
 #define netfs_write_traces                                     \
+       EM(netfs_write_trace_copy_to_cache,     "COPY2CACH")    \
        EM(netfs_write_trace_dio_write,         "DIO-WRITE")    \
-       EM(netfs_write_trace_launder,           "LAUNDER  ")    \
        EM(netfs_write_trace_unbuffered_write,  "UNB-WRITE")    \
        EM(netfs_write_trace_writeback,         "WRITEBACK")    \
        E_(netfs_write_trace_writethrough,      "WRITETHRU")
@@ -34,9 +34,9 @@
        EM(NETFS_READAHEAD,                     "RA")           \
        EM(NETFS_READPAGE,                      "RP")           \
        EM(NETFS_READ_FOR_WRITE,                "RW")           \
+       EM(NETFS_COPY_TO_CACHE,                 "CC")           \
        EM(NETFS_WRITEBACK,                     "WB")           \
        EM(NETFS_WRITETHROUGH,                  "WT")           \
-       EM(NETFS_LAUNDER_WRITE,                 "LW")           \
        EM(NETFS_UNBUFFERED_WRITE,              "UW")           \
        EM(NETFS_DIO_READ,                      "DR")           \
        E_(NETFS_DIO_WRITE,                     "DW")
 #define netfs_rreq_traces                                      \
        EM(netfs_rreq_trace_assess,             "ASSESS ")      \
        EM(netfs_rreq_trace_copy,               "COPY   ")      \
+       EM(netfs_rreq_trace_collect,            "COLLECT")      \
        EM(netfs_rreq_trace_done,               "DONE   ")      \
        EM(netfs_rreq_trace_free,               "FREE   ")      \
        EM(netfs_rreq_trace_redirty,            "REDIRTY")      \
        EM(netfs_rreq_trace_resubmit,           "RESUBMT")      \
+       EM(netfs_rreq_trace_set_pause,          "PAUSE  ")      \
        EM(netfs_rreq_trace_unlock,             "UNLOCK ")      \
        EM(netfs_rreq_trace_unmark,             "UNMARK ")      \
        EM(netfs_rreq_trace_wait_ip,            "WAIT-IP")      \
+       EM(netfs_rreq_trace_wait_pause,         "WT-PAUS")      \
        EM(netfs_rreq_trace_wake_ip,            "WAKE-IP")      \
+       EM(netfs_rreq_trace_unpause,            "UNPAUSE")      \
        E_(netfs_rreq_trace_write_done,         "WR-DONE")
 
 #define netfs_sreq_sources                                     \
        E_(NETFS_INVALID_WRITE,                 "INVL")
 
 #define netfs_sreq_traces                                      \
+       EM(netfs_sreq_trace_discard,            "DSCRD")        \
        EM(netfs_sreq_trace_download_instead,   "RDOWN")        \
+       EM(netfs_sreq_trace_fail,               "FAIL ")        \
        EM(netfs_sreq_trace_free,               "FREE ")        \
        EM(netfs_sreq_trace_limited,            "LIMIT")        \
        EM(netfs_sreq_trace_prepare,            "PREP ")        \
+       EM(netfs_sreq_trace_prep_failed,        "PRPFL")        \
        EM(netfs_sreq_trace_resubmit_short,     "SHORT")        \
+       EM(netfs_sreq_trace_retry,              "RETRY")        \
        EM(netfs_sreq_trace_submit,             "SUBMT")        \
        EM(netfs_sreq_trace_terminated,         "TERM ")        \
        EM(netfs_sreq_trace_write,              "WRITE")        \
@@ -88,6 +96,7 @@
 #define netfs_rreq_ref_traces                                  \
        EM(netfs_rreq_trace_get_for_outstanding,"GET OUTSTND")  \
        EM(netfs_rreq_trace_get_subreq,         "GET SUBREQ ")  \
+       EM(netfs_rreq_trace_get_work,           "GET WORK   ")  \
        EM(netfs_rreq_trace_put_complete,       "PUT COMPLT ")  \
        EM(netfs_rreq_trace_put_discard,        "PUT DISCARD")  \
        EM(netfs_rreq_trace_put_failed,         "PUT FAILED ")  \
        EM(netfs_rreq_trace_put_return,         "PUT RETURN ")  \
        EM(netfs_rreq_trace_put_subreq,         "PUT SUBREQ ")  \
        EM(netfs_rreq_trace_put_work,           "PUT WORK   ")  \
+       EM(netfs_rreq_trace_put_work_complete,  "PUT WORK CP")  \
+       EM(netfs_rreq_trace_put_work_nq,        "PUT WORK NQ")  \
        EM(netfs_rreq_trace_see_work,           "SEE WORK   ")  \
        E_(netfs_rreq_trace_new,                "NEW        ")
 
 #define netfs_sreq_ref_traces                                  \
        EM(netfs_sreq_trace_get_copy_to_cache,  "GET COPY2C ")  \
        EM(netfs_sreq_trace_get_resubmit,       "GET RESUBMIT") \
+       EM(netfs_sreq_trace_get_submit,         "GET SUBMIT")   \
        EM(netfs_sreq_trace_get_short_read,     "GET SHORTRD")  \
        EM(netfs_sreq_trace_new,                "NEW        ")  \
+       EM(netfs_sreq_trace_put_cancel,         "PUT CANCEL ")  \
        EM(netfs_sreq_trace_put_clear,          "PUT CLEAR  ")  \
        EM(netfs_sreq_trace_put_discard,        "PUT DISCARD")  \
+       EM(netfs_sreq_trace_put_done,           "PUT DONE   ")  \
        EM(netfs_sreq_trace_put_failed,         "PUT FAILED ")  \
        EM(netfs_sreq_trace_put_merged,         "PUT MERGED ")  \
        EM(netfs_sreq_trace_put_no_copy,        "PUT NO COPY")  \
+       EM(netfs_sreq_trace_put_oom,            "PUT OOM    ")  \
        EM(netfs_sreq_trace_put_wip,            "PUT WIP    ")  \
        EM(netfs_sreq_trace_put_work,           "PUT WORK   ")  \
        E_(netfs_sreq_trace_put_terminated,     "PUT TERM   ")
        EM(netfs_streaming_filled_page,         "mod-streamw-f") \
        EM(netfs_streaming_cont_filled_page,    "mod-streamw-f+") \
        /* The rest are for writeback */                        \
+       EM(netfs_folio_trace_cancel_copy,       "cancel-copy")  \
        EM(netfs_folio_trace_clear,             "clear")        \
-       EM(netfs_folio_trace_clear_s,           "clear-s")      \
+       EM(netfs_folio_trace_clear_cc,          "clear-cc")     \
        EM(netfs_folio_trace_clear_g,           "clear-g")      \
-       EM(netfs_folio_trace_copy_to_cache,     "copy")         \
-       EM(netfs_folio_trace_end_copy,          "end-copy")     \
+       EM(netfs_folio_trace_clear_s,           "clear-s")      \
+       EM(netfs_folio_trace_copy_to_cache,     "mark-copy")    \
        EM(netfs_folio_trace_filled_gaps,       "filled-gaps")  \
        EM(netfs_folio_trace_kill,              "kill")         \
-       EM(netfs_folio_trace_launder,           "launder")      \
+       EM(netfs_folio_trace_kill_cc,           "kill-cc")      \
+       EM(netfs_folio_trace_kill_g,            "kill-g")       \
+       EM(netfs_folio_trace_kill_s,            "kill-s")       \
        EM(netfs_folio_trace_mkwrite,           "mkwrite")      \
        EM(netfs_folio_trace_mkwrite_plus,      "mkwrite+")     \
+       EM(netfs_folio_trace_not_under_wback,   "!wback")       \
        EM(netfs_folio_trace_read_gaps,         "read-gaps")    \
-       EM(netfs_folio_trace_redirty,           "redirty")      \
        EM(netfs_folio_trace_redirtied,         "redirtied")    \
        EM(netfs_folio_trace_store,             "store")        \
+       EM(netfs_folio_trace_store_copy,        "store-copy")   \
        EM(netfs_folio_trace_store_plus,        "store+")       \
        EM(netfs_folio_trace_wthru,             "wthru")        \
        E_(netfs_folio_trace_wthru_plus,        "wthru+")
 
+#define netfs_collect_contig_traces                            \
+       EM(netfs_contig_trace_collect,          "Collect")      \
+       EM(netfs_contig_trace_jump,             "-->JUMP-->")   \
+       E_(netfs_contig_trace_unlock,           "Unlock")
+
 #ifndef __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
 #define __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
 
@@ -158,6 +182,7 @@ enum netfs_failure { netfs_failures } __mode(byte);
 enum netfs_rreq_ref_trace { netfs_rreq_ref_traces } __mode(byte);
 enum netfs_sreq_ref_trace { netfs_sreq_ref_traces } __mode(byte);
 enum netfs_folio_trace { netfs_folio_traces } __mode(byte);
+enum netfs_collect_contig_trace { netfs_collect_contig_traces } __mode(byte);
 
 #endif
 
@@ -179,6 +204,7 @@ netfs_failures;
 netfs_rreq_ref_traces;
 netfs_sreq_ref_traces;
 netfs_folio_traces;
+netfs_collect_contig_traces;
 
 /*
  * Now redefine the EM() and E_() macros to map the enums to the strings that
@@ -279,7 +305,7 @@ TRACE_EVENT(netfs_sreq,
                    __entry->start      = sreq->start;
                           ),
 
-           TP_printk("R=%08x[%u] %s %s f=%02x s=%llx %zx/%zx e=%d",
+           TP_printk("R=%08x[%x] %s %s f=%02x s=%llx %zx/%zx e=%d",
                      __entry->rreq, __entry->index,
                      __print_symbolic(__entry->source, netfs_sreq_sources),
                      __print_symbolic(__entry->what, netfs_sreq_traces),
@@ -319,7 +345,7 @@ TRACE_EVENT(netfs_failure,
                    __entry->start      = sreq ? sreq->start : 0;
                           ),
 
-           TP_printk("R=%08x[%d] %s f=%02x s=%llx %zx/%zx %s e=%d",
+           TP_printk("R=%08x[%x] %s f=%02x s=%llx %zx/%zx %s e=%d",
                      __entry->rreq, __entry->index,
                      __print_symbolic(__entry->source, netfs_sreq_sources),
                      __entry->flags,
@@ -412,16 +438,18 @@ TRACE_EVENT(netfs_write_iter,
                    __field(unsigned long long,         start           )
                    __field(size_t,                     len             )
                    __field(unsigned int,               flags           )
+                   __field(unsigned int,               ino             )
                             ),
 
            TP_fast_assign(
                    __entry->start      = iocb->ki_pos;
                    __entry->len        = iov_iter_count(from);
+                   __entry->ino        = iocb->ki_filp->f_inode->i_ino;
                    __entry->flags      = iocb->ki_flags;
                           ),
 
-           TP_printk("WRITE-ITER s=%llx l=%zx f=%x",
-                     __entry->start, __entry->len, __entry->flags)
+           TP_printk("WRITE-ITER i=%x s=%llx l=%zx f=%x",
+                     __entry->ino, __entry->start, __entry->len, __entry->flags)
            );
 
 TRACE_EVENT(netfs_write,
@@ -433,9 +461,10 @@ TRACE_EVENT(netfs_write,
            TP_STRUCT__entry(
                    __field(unsigned int,               wreq            )
                    __field(unsigned int,               cookie          )
+                   __field(unsigned int,               ino             )
                    __field(enum netfs_write_trace,     what            )
                    __field(unsigned long long,         start           )
-                   __field(size_t,                     len             )
+                   __field(unsigned long long,         len             )
                             ),
 
            TP_fast_assign(
@@ -443,18 +472,213 @@ TRACE_EVENT(netfs_write,
                    struct fscache_cookie *__cookie = netfs_i_cookie(__ctx);
                    __entry->wreq       = wreq->debug_id;
                    __entry->cookie     = __cookie ? __cookie->debug_id : 0;
+                   __entry->ino        = wreq->inode->i_ino;
                    __entry->what       = what;
                    __entry->start      = wreq->start;
                    __entry->len        = wreq->len;
                           ),
 
-           TP_printk("R=%08x %s c=%08x by=%llx-%llx",
+           TP_printk("R=%08x %s c=%08x i=%x by=%llx-%llx",
                      __entry->wreq,
                      __print_symbolic(__entry->what, netfs_write_traces),
                      __entry->cookie,
+                     __entry->ino,
                      __entry->start, __entry->start + __entry->len - 1)
            );
 
+TRACE_EVENT(netfs_collect,
+           TP_PROTO(const struct netfs_io_request *wreq),
+
+           TP_ARGS(wreq),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,               wreq            )
+                   __field(unsigned int,               len             )
+                   __field(unsigned long long,         transferred     )
+                   __field(unsigned long long,         start           )
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->start      = wreq->start;
+                   __entry->len        = wreq->len;
+                   __entry->transferred = wreq->transferred;
+                          ),
+
+           TP_printk("R=%08x s=%llx-%llx",
+                     __entry->wreq,
+                     __entry->start + __entry->transferred,
+                     __entry->start + __entry->len)
+           );
+
+TRACE_EVENT(netfs_collect_contig,
+           TP_PROTO(const struct netfs_io_request *wreq, unsigned long long to,
+                    enum netfs_collect_contig_trace type),
+
+           TP_ARGS(wreq, to, type),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,               wreq)
+                   __field(enum netfs_collect_contig_trace, type)
+                   __field(unsigned long long,         contiguity)
+                   __field(unsigned long long,         to)
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->type       = type;
+                   __entry->contiguity = wreq->contiguity;
+                   __entry->to         = to;
+                          ),
+
+           TP_printk("R=%08x %llx -> %llx %s",
+                     __entry->wreq,
+                     __entry->contiguity,
+                     __entry->to,
+                     __print_symbolic(__entry->type, netfs_collect_contig_traces))
+           );
+
+TRACE_EVENT(netfs_collect_sreq,
+           TP_PROTO(const struct netfs_io_request *wreq,
+                    const struct netfs_io_subrequest *subreq),
+
+           TP_ARGS(wreq, subreq),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,               wreq            )
+                   __field(unsigned int,               subreq          )
+                   __field(unsigned int,               stream          )
+                   __field(unsigned int,               len             )
+                   __field(unsigned int,               transferred     )
+                   __field(unsigned long long,         start           )
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->subreq     = subreq->debug_index;
+                   __entry->stream     = subreq->stream_nr;
+                   __entry->start      = subreq->start;
+                   __entry->len        = subreq->len;
+                   __entry->transferred = subreq->transferred;
+                          ),
+
+           TP_printk("R=%08x[%u:%02x] s=%llx t=%x/%x",
+                     __entry->wreq, __entry->stream, __entry->subreq,
+                     __entry->start, __entry->transferred, __entry->len)
+           );
+
+TRACE_EVENT(netfs_collect_folio,
+           TP_PROTO(const struct netfs_io_request *wreq,
+                    const struct folio *folio,
+                    unsigned long long fend,
+                    unsigned long long collected_to),
+
+           TP_ARGS(wreq, folio, fend, collected_to),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       wreq            )
+                   __field(unsigned long,      index           )
+                   __field(unsigned long long, fend            )
+                   __field(unsigned long long, cleaned_to      )
+                   __field(unsigned long long, collected_to    )
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->index      = folio->index;
+                   __entry->fend       = fend;
+                   __entry->cleaned_to = wreq->cleaned_to;
+                   __entry->collected_to = collected_to;
+                          ),
+
+           TP_printk("R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx",
+                     __entry->wreq, __entry->index,
+                     (unsigned long long)__entry->index * PAGE_SIZE, __entry->fend,
+                     __entry->cleaned_to, __entry->collected_to)
+           );
+
+TRACE_EVENT(netfs_collect_state,
+           TP_PROTO(const struct netfs_io_request *wreq,
+                    unsigned long long collected_to,
+                    unsigned int notes),
+
+           TP_ARGS(wreq, collected_to, notes),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       wreq            )
+                   __field(unsigned int,       notes           )
+                   __field(unsigned long long, collected_to    )
+                   __field(unsigned long long, cleaned_to      )
+                   __field(unsigned long long, contiguity      )
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->notes      = notes;
+                   __entry->collected_to = collected_to;
+                   __entry->cleaned_to = wreq->cleaned_to;
+                   __entry->contiguity = wreq->contiguity;
+                          ),
+
+           TP_printk("R=%08x cto=%llx fto=%llx ctg=%llx n=%x",
+                     __entry->wreq, __entry->collected_to,
+                     __entry->cleaned_to, __entry->contiguity,
+                     __entry->notes)
+           );
+
+TRACE_EVENT(netfs_collect_gap,
+           TP_PROTO(const struct netfs_io_request *wreq,
+                    const struct netfs_io_stream *stream,
+                    unsigned long long jump_to, char type),
+
+           TP_ARGS(wreq, stream, jump_to, type),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       wreq)
+                   __field(unsigned char,      stream)
+                   __field(unsigned char,      type)
+                   __field(unsigned long long, from)
+                   __field(unsigned long long, to)
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->stream     = stream->stream_nr;
+                   __entry->from       = stream->collected_to;
+                   __entry->to         = jump_to;
+                   __entry->type       = type;
+                          ),
+
+           TP_printk("R=%08x[%x:] %llx->%llx %c",
+                     __entry->wreq, __entry->stream,
+                     __entry->from, __entry->to, __entry->type)
+           );
+
+TRACE_EVENT(netfs_collect_stream,
+           TP_PROTO(const struct netfs_io_request *wreq,
+                    const struct netfs_io_stream *stream),
+
+           TP_ARGS(wreq, stream),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       wreq)
+                   __field(unsigned char,      stream)
+                   __field(unsigned long long, collected_to)
+                   __field(unsigned long long, front)
+                            ),
+
+           TP_fast_assign(
+                   __entry->wreq       = wreq->debug_id;
+                   __entry->stream     = stream->stream_nr;
+                   __entry->collected_to = stream->collected_to;
+                   __entry->front      = stream->front ? stream->front->start : UINT_MAX;
+                          ),
+
+           TP_printk("R=%08x[%x:] cto=%llx frn=%llx",
+                     __entry->wreq, __entry->stream,
+                     __entry->collected_to, __entry->front)
+           );
+
 #undef EM
 #undef E_
 #endif /* _TRACE_NETFS_H */
index 2ef9c719772afbd6002c4b658c3dcaaa99da1246..31b3e0d3e65f78ce87216b72e634b36913a777f0 100644 (file)
@@ -707,6 +707,33 @@ TRACE_EVENT_RCU(rcu_invoke_kfree_bulk_callback,
                __entry->rcuname, __entry->p, __entry->nr_records)
 );
 
+/*
+ * Tracepoint for a normal synchronize_rcu() states. The first argument
+ * is the RCU flavor, the second argument is a pointer to rcu_head the
+ * last one is an event.
+ */
+TRACE_EVENT_RCU(rcu_sr_normal,
+
+       TP_PROTO(const char *rcuname, struct rcu_head *rhp, const char *srevent),
+
+       TP_ARGS(rcuname, rhp, srevent),
+
+       TP_STRUCT__entry(
+               __field(const char *, rcuname)
+               __field(void *, rhp)
+               __field(const char *, srevent)
+       ),
+
+       TP_fast_assign(
+               __entry->rcuname = rcuname;
+               __entry->rhp = rhp;
+               __entry->srevent = srevent;
+       ),
+
+       TP_printk("%s rhp=0x%p event=%s",
+               __entry->rcuname, __entry->rhp, __entry->srevent)
+);
+
 /*
  * Tracepoint for exiting rcu_do_batch after RCU callbacks have been
  * invoked.  The first argument is the name of the RCU flavor,
index 422c1ad9484dc89d93c2712a04dc70e56bcd7137..1273004811234a139217bf6cfc1920a36ae41af1 100644 (file)
@@ -7,6 +7,8 @@
 
 #include <linux/tracepoint.h>
 
+#define TRACE_SCMI_MAX_TAG_LEN 6
+
 TRACE_EVENT(scmi_fc_call,
        TP_PROTO(u8 protocol_id, u8 msg_id, u32 res_id, u32 val1, u32 val2),
        TP_ARGS(protocol_id, msg_id, res_id, val1, val2),
@@ -150,7 +152,7 @@ TRACE_EVENT(scmi_msg_dump,
                __field(u8, channel_id)
                __field(u8, protocol_id)
                __field(u8, msg_id)
-               __array(char, tag, 5)
+               __array(char, tag, TRACE_SCMI_MAX_TAG_LEN)
                __field(u16, seq)
                __field(int, status)
                __field(size_t, len)
@@ -162,7 +164,7 @@ TRACE_EVENT(scmi_msg_dump,
                __entry->channel_id = channel_id;
                __entry->protocol_id = protocol_id;
                __entry->msg_id = msg_id;
-               strscpy(__entry->tag, tag, 5);
+               strscpy(__entry->tag, tag, TRACE_SCMI_MAX_TAG_LEN);
                __entry->seq = seq;
                __entry->status = status;
                __entry->len = len;
index 282e90aeb163c0288590995b38fe011b19e85111..c0bcc185fa48f85244d3f3b0de01a1c979732b15 100644 (file)
@@ -8,6 +8,14 @@
 #define F_SETLEASE     (F_LINUX_SPECIFIC_BASE + 0)
 #define F_GETLEASE     (F_LINUX_SPECIFIC_BASE + 1)
 
+/*
+ * Request nofications on a directory.
+ * See below for events that may be notified.
+ */
+#define F_NOTIFY       (F_LINUX_SPECIFIC_BASE + 2)
+
+#define F_DUPFD_QUERY  (F_LINUX_SPECIFIC_BASE + 3)
+
 /*
  * Cancel a blocking posix lock; internal use only until we expose an
  * asynchronous lock api to userspace:
 /* Create a file descriptor with FD_CLOEXEC set. */
 #define F_DUPFD_CLOEXEC        (F_LINUX_SPECIFIC_BASE + 6)
 
-/*
- * Request nofications on a directory.
- * See below for events that may be notified.
- */
-#define F_NOTIFY       (F_LINUX_SPECIFIC_BASE+2)
-
 /*
  * Set and get of pipe page size array
  */
index 2f2ee82d55175d052c0214a7e29da5d6ce2738ab..67626d53531664d0a65fbcf62585204e41588d88 100644 (file)
@@ -126,8 +126,9 @@ struct statx {
        __u64   stx_mnt_id;
        __u32   stx_dio_mem_align;      /* Memory buffer alignment for direct I/O */
        __u32   stx_dio_offset_align;   /* File offset alignment for direct I/O */
+       __u64   stx_subvol;     /* Subvolume identifier */
        /* 0xa0 */
-       __u64   __spare3[12];   /* Spare space for future expansion */
+       __u64   __spare3[11];   /* Spare space for future expansion */
        /* 0x100 */
 };
 
@@ -155,6 +156,7 @@ struct statx {
 #define STATX_MNT_ID           0x00001000U     /* Got stx_mnt_id */
 #define STATX_DIOALIGN         0x00002000U     /* Want/got direct I/O alignment info */
 #define STATX_MNT_ID_UNIQUE    0x00004000U     /* Want/got extended stx_mount_id */
+#define STATX_SUBVOL           0x00008000U     /* Want/got stx_subvol */
 
 #define STATX__RESERVED                0x80000000U     /* Reserved for future struct statx expansion */
 
index 23e57164693c4fd89758fc5d8c5a080b9be24b24..d0430bee82921c398cdce7cbcaa2051eaf24d428 100644 (file)
@@ -56,6 +56,7 @@
  */
 #define TEE_IMPL_ID_OPTEE      1
 #define TEE_IMPL_ID_AMDTEE     2
+#define TEE_IMPL_ID_TSTEE      3
 
 /*
  * OP-TEE specific capabilities
index 6a77328be114525b5eabd8138c25fc1b99d517b0..594b66e1639534132d31e91599d2cc39dc0ce540 100644 (file)
@@ -228,7 +228,7 @@ enum {
 #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
 
 /*
- * Generic LSM security context for comunicating to user space
+ * Generic LSM security context for communicating to user space
  * NOTE: Same format as sadb_x_sec_ctx
  */
 struct xfrm_user_sec_ctx {
index aa02aec6aa7d29432f1974003900fce14bf14452..664bedb9a71fbe97c9726c1397d5c8b2043d1da4 100644 (file)
@@ -1899,11 +1899,11 @@ config RUST
        bool "Rust support"
        depends on HAVE_RUST
        depends on RUST_IS_AVAILABLE
+       depends on !CFI_CLANG
        depends on !MODVERSIONS
        depends on !GCC_PLUGINS
        depends on !RANDSTRUCT
        depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
-       select CONSTRUCTORS
        help
          Enables Rust support in the kernel.
 
index c170a2b8d2cf21f06d1c5af8bf57edecb94aaa95..380b9ce1d30144c9a5f7ded984b45d03f90bc813 100644 (file)
@@ -471,7 +471,7 @@ static void io_prep_async_work(struct io_kiocb *req)
 
                /* don't serialize this request if the fs doesn't need it */
                if (should_hash && (req->file->f_flags & O_DIRECT) &&
-                   (req->file->f_mode & FMODE_DIO_PARALLEL_WRITE))
+                   (req->file->f_op->fop_flags & FOP_DIO_PARALLEL_WRITE))
                        should_hash = false;
                if (should_hash || (ctx->flags & IORING_SETUP_IOPOLL))
                        io_wq_hash_work(&req->work, file_inode(req->file));
index c8d48287439e5a06d19113ecb07f1c05db47dc3f..2382116aa4b20e99918ede2e40a9066ad619237f 100644 (file)
@@ -683,7 +683,8 @@ static bool io_rw_should_retry(struct io_kiocb *req)
         * just use poll if we can, and don't attempt if the fs doesn't
         * support callback based unlocks
         */
-       if (io_file_can_poll(req) || !(req->file->f_mode & FMODE_BUF_RASYNC))
+       if (io_file_can_poll(req) ||
+           !(req->file->f_op->fop_flags & FOP_BUFFER_RASYNC))
                return false;
 
        wait->wait.func = io_async_buf_func;
@@ -1029,10 +1030,10 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)
                if (unlikely(!io_file_supports_nowait(req)))
                        goto copy_iov;
 
-               /* File path supports NOWAIT for non-direct_IO only for block devices. */
+               /* Check if we can support NOWAIT. */
                if (!(kiocb->ki_flags & IOCB_DIRECT) &&
-                       !(kiocb->ki_filp->f_mode & FMODE_BUF_WASYNC) &&
-                       (req->flags & REQ_F_ISREG))
+                   !(req->file->f_op->fop_flags & FOP_BUFFER_WASYNC) &&
+                   (req->flags & REQ_F_ISREG))
                        goto copy_iov;
 
                kiocb->ki_flags |= IOCB_NOWAIT;
index a89f001a8bf07250baaca4455c22263ce5ab4769..3e3071252dac65350588cd3eb04b84f80a38411b 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -662,8 +662,8 @@ static const struct file_operations shm_file_operations = {
 };
 
 /*
- * shm_file_operations_huge is now identical to shm_file_operations,
- * but we keep it distinct for the sake of is_file_shm_hugepages().
+ * shm_file_operations_huge is now identical to shm_file_operations
+ * except for fop_flags
  */
 static const struct file_operations shm_file_operations_huge = {
        .mmap           = shm_mmap,
@@ -672,13 +672,9 @@ static const struct file_operations shm_file_operations_huge = {
        .get_unmapped_area      = shm_get_unmapped_area,
        .llseek         = noop_llseek,
        .fallocate      = shm_fallocate,
+       .fop_flags      = FOP_HUGE_PAGES,
 };
 
-bool is_file_shm_hugepages(struct file *file)
-{
-       return file->f_op == &shm_file_operations_huge;
-}
-
 static const struct vm_operations_struct shm_vm_ops = {
        .open   = shm_open,     /* callback for a new vm-area open */
        .close  = shm_close,    /* callback for when the vm-area is released */
index c5a9fcd2d622819cc1f5b0f5cfd772514ee5f423..29b2cd00df2ccf2b991b9b78f4514b76c87ee354 100644 (file)
@@ -19,7 +19,7 @@ int main(void)
        DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS);
        DEFINE(MAX_NR_ZONES, __MAX_NR_ZONES);
 #ifdef CONFIG_SMP
-       DEFINE(NR_CPUS_BITS, bits_per(CONFIG_NR_CPUS));
+       DEFINE(NR_CPUS_BITS, order_base_2(CONFIG_NR_CPUS));
 #endif
        DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
 #ifdef CONFIG_LRU_GEN
index bc25f5098a254b6ceea74267be15026ecd3418fa..4100df44c66529277893c4ad342a82efce2259cf 100644 (file)
@@ -28,7 +28,7 @@ config BPF_SYSCALL
        bool "Enable bpf() system call"
        select BPF
        select IRQ_WORK
-       select TASKS_RCU if PREEMPTION
+       select NEED_TASKS_RCU
        select TASKS_TRACE_RCU
        select BINARY_PRINTF
        select NET_SOCK_MSG if NET
index 696bc55de8e82ea9358ede9c222b4927871e60be..1ea5ce5bb59933ac4449567c52f1981c8df8a139 100644 (file)
@@ -2942,6 +2942,15 @@ bool __weak bpf_jit_supports_arena(void)
        return false;
 }
 
+u64 __weak bpf_arch_uaddress_limit(void)
+{
+#if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
+       return TASK_SIZE;
+#else
+       return 0;
+#endif
+}
+
 /* Return TRUE if the JIT backend satisfies the following two conditions:
  * 1) JIT backend supports atomic_xchg() on pointer-sized words.
  * 2) Under the specific arch, the implementation of xchg() is the same
index db7599c59c78a66f1b85ef969ba64be084edd181..88673a4267ebdfc118e3048dca761d08565c5568 100644 (file)
@@ -333,7 +333,7 @@ static void bpf_tramp_image_put(struct bpf_tramp_image *im)
                int err = bpf_arch_text_poke(im->ip_after_call, BPF_MOD_JUMP,
                                             NULL, im->ip_epilogue);
                WARN_ON(err);
-               if (IS_ENABLED(CONFIG_PREEMPTION))
+               if (IS_ENABLED(CONFIG_TASKS_RCU))
                        call_rcu_tasks(&im->rcu, __bpf_tramp_image_put_rcu_tasks);
                else
                        percpu_ref_kill(&im->pcref);
index 98188379d5c77d79d3a5e764659ed4426f931d14..cb7ad1f795e18b1abec57dc5e40f2d852416bb04 100644 (file)
@@ -18289,8 +18289,7 @@ static int resolve_pseudo_ldimm64(struct bpf_verifier_env *env)
                        f = fdget(fd);
                        map = __bpf_map_get(f);
                        if (IS_ERR(map)) {
-                               verbose(env, "fd %d is not pointing to valid bpf_map\n",
-                                       insn[0].imm);
+                               verbose(env, "fd %d is not pointing to valid bpf_map\n", fd);
                                return PTR_ERR(map);
                        }
 
@@ -19676,6 +19675,36 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
                        goto next_insn;
                }
 
+               /* Make it impossible to de-reference a userspace address */
+               if (BPF_CLASS(insn->code) == BPF_LDX &&
+                   (BPF_MODE(insn->code) == BPF_PROBE_MEM ||
+                    BPF_MODE(insn->code) == BPF_PROBE_MEMSX)) {
+                       struct bpf_insn *patch = &insn_buf[0];
+                       u64 uaddress_limit = bpf_arch_uaddress_limit();
+
+                       if (!uaddress_limit)
+                               goto next_insn;
+
+                       *patch++ = BPF_MOV64_REG(BPF_REG_AX, insn->src_reg);
+                       if (insn->off)
+                               *patch++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_AX, insn->off);
+                       *patch++ = BPF_ALU64_IMM(BPF_RSH, BPF_REG_AX, 32);
+                       *patch++ = BPF_JMP_IMM(BPF_JLE, BPF_REG_AX, uaddress_limit >> 32, 2);
+                       *patch++ = *insn;
+                       *patch++ = BPF_JMP_IMM(BPF_JA, 0, 0, 1);
+                       *patch++ = BPF_MOV64_IMM(insn->dst_reg, 0);
+
+                       cnt = patch - insn_buf;
+                       new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
+                       if (!new_prog)
+                               return -ENOMEM;
+
+                       delta    += cnt - 1;
+                       env->prog = prog = new_prog;
+                       insn      = new_prog->insnsi + i + delta;
+                       goto next_insn;
+               }
+
                /* Implement LD_ABS and LD_IND with a rewrite, if supported by the program type. */
                if (BPF_CLASS(insn->code) == BPF_LD &&
                    (BPF_MODE(insn->code) == BPF_ABS ||
index 07ad53b7f11952080e890ed91f99f3e762bf984d..63447eb85dab6bd0fa2ab23c25bffdf788a2b9c1 100644 (file)
@@ -3196,6 +3196,7 @@ void __init boot_cpu_hotplug_init(void)
        this_cpu_write(cpuhp_state.target, CPUHP_ONLINE);
 }
 
+#ifdef CONFIG_CPU_MITIGATIONS
 /*
  * These are used for a global "mitigations=" cmdline option for toggling
  * optional CPU mitigations.
@@ -3206,9 +3207,7 @@ enum cpu_mitigations {
        CPU_MITIGATIONS_AUTO_NOSMT,
 };
 
-static enum cpu_mitigations cpu_mitigations __ro_after_init =
-       IS_ENABLED(CONFIG_SPECULATION_MITIGATIONS) ? CPU_MITIGATIONS_AUTO :
-                                                    CPU_MITIGATIONS_OFF;
+static enum cpu_mitigations cpu_mitigations __ro_after_init = CPU_MITIGATIONS_AUTO;
 
 static int __init mitigations_parse_cmdline(char *arg)
 {
@@ -3224,7 +3223,6 @@ static int __init mitigations_parse_cmdline(char *arg)
 
        return 0;
 }
-early_param("mitigations", mitigations_parse_cmdline);
 
 /* mitigations=off */
 bool cpu_mitigations_off(void)
@@ -3239,3 +3237,11 @@ bool cpu_mitigations_auto_nosmt(void)
        return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
 }
 EXPORT_SYMBOL_GPL(cpu_mitigations_auto_nosmt);
+#else
+static int __init mitigations_parse_cmdline(char *arg)
+{
+       pr_crit("Kernel compiled without mitigations, ignoring 'mitigations'; system may still be vulnerable\n");
+       return 0;
+}
+#endif
+early_param("mitigations", mitigations_parse_cmdline);
index a5e0dfc44d24e22641e72bb0362511a33b23a1fd..0de66f0ff43aba1f64505d70b86d9faac8bc43ff 100644 (file)
@@ -1798,6 +1798,7 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
                mem->for_alloc = true;
 #ifdef CONFIG_SWIOTLB_DYNAMIC
                spin_lock_init(&mem->lock);
+               INIT_LIST_HEAD_RCU(&mem->pools);
 #endif
                add_mem_pool(mem, pool);
 
index 015586217875319dec892e73ff13832600ff5646..0c17b4c83e1ca0714ac76a9255ddf79efd226e18 100644 (file)
@@ -304,6 +304,7 @@ static long test_array[3 * PAGE_SIZE / sizeof(long)];
 static struct {
        long val[8];
 } test_struct;
+static long __data_racy test_data_racy;
 static DEFINE_SEQLOCK(test_seqlock);
 static DEFINE_SPINLOCK(test_spinlock);
 static DEFINE_MUTEX(test_mutex);
@@ -358,6 +359,8 @@ static noinline void test_kernel_write_uninstrumented(void) { test_var++; }
 
 static noinline void test_kernel_data_race(void) { data_race(test_var++); }
 
+static noinline void test_kernel_data_racy_qualifier(void) { test_data_racy++; }
+
 static noinline void test_kernel_assert_writer(void)
 {
        ASSERT_EXCLUSIVE_WRITER(test_var);
@@ -1009,6 +1012,19 @@ static void test_data_race(struct kunit *test)
        KUNIT_EXPECT_FALSE(test, match_never);
 }
 
+/* Test the __data_racy type qualifier. */
+__no_kcsan
+static void test_data_racy_qualifier(struct kunit *test)
+{
+       bool match_never = false;
+
+       begin_test_checks(test_kernel_data_racy_qualifier, test_kernel_data_racy_qualifier);
+       do {
+               match_never = report_available();
+       } while (!end_test_checks(match_never));
+       KUNIT_EXPECT_FALSE(test, match_never);
+}
+
 __no_kcsan
 static void test_assert_exclusive_writer(struct kunit *test)
 {
@@ -1424,6 +1440,7 @@ static struct kunit_case kcsan_test_cases[] = {
        KCSAN_KUNIT_CASE(test_read_plain_atomic_rmw),
        KCSAN_KUNIT_CASE(test_zero_size_access),
        KCSAN_KUNIT_CASE(test_data_race),
+       KCSAN_KUNIT_CASE(test_data_racy_qualifier),
        KCSAN_KUNIT_CASE(test_assert_exclusive_writer),
        KCSAN_KUNIT_CASE(test_assert_exclusive_access),
        KCSAN_KUNIT_CASE(test_assert_exclusive_access_writer),
index e7d2dd2675931fac627947959f3fbb9e93aae05b..3e079de0f5b434bd394033f08a38a00228c07432 100644 (file)
@@ -31,7 +31,7 @@ config PREEMPT_RCU
 
 config TINY_RCU
        bool
-       default y if !PREEMPTION && !SMP
+       default y if !PREEMPT_RCU && !SMP
        help
          This option selects the RCU implementation that is
          designed for UP systems from which real-time response
@@ -85,9 +85,13 @@ config FORCE_TASKS_RCU
          idle, and user-mode execution as quiescent states.  Not for
          manual selection in most cases.
 
-config TASKS_RCU
+config NEED_TASKS_RCU
        bool
        default n
+
+config TASKS_RCU
+       bool
+       default NEED_TASKS_RCU && (PREEMPTION || PREEMPT_AUTO)
        select IRQ_WORK
 
 config FORCE_TASKS_RUDE_RCU
index 86fce206560e83f05e3a57114e5771e0c0a76b7d..38238e595a61a45fd263df234e199c722149968b 100644 (file)
@@ -522,12 +522,18 @@ static inline void show_rcu_tasks_gp_kthreads(void) {}
 
 #ifdef CONFIG_TASKS_RCU
 struct task_struct *get_rcu_tasks_gp_kthread(void);
+void rcu_tasks_get_gp_data(int *flags, unsigned long *gp_seq);
 #endif // # ifdef CONFIG_TASKS_RCU
 
 #ifdef CONFIG_TASKS_RUDE_RCU
 struct task_struct *get_rcu_tasks_rude_gp_kthread(void);
+void rcu_tasks_rude_get_gp_data(int *flags, unsigned long *gp_seq);
 #endif // # ifdef CONFIG_TASKS_RUDE_RCU
 
+#ifdef CONFIG_TASKS_TRACE_RCU
+void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq);
+#endif
+
 #ifdef CONFIG_TASKS_RCU_GENERIC
 void tasks_cblist_init_generic(void);
 #else /* #ifdef CONFIG_TASKS_RCU_GENERIC */
@@ -557,8 +563,7 @@ static inline void rcu_set_jiffies_lazy_flush(unsigned long j) { }
 #endif
 
 #if defined(CONFIG_TREE_RCU)
-void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags,
-                           unsigned long *gp_seq);
+void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq);
 void do_trace_rcu_torture_read(const char *rcutorturename,
                               struct rcu_head *rhp,
                               unsigned long secs,
@@ -566,8 +571,7 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
                               unsigned long c);
 void rcu_gp_set_torture_wait(int duration);
 #else
-static inline void rcutorture_get_gp_data(enum rcutorture_type test_type,
-                                         int *flags, unsigned long *gp_seq)
+static inline void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq)
 {
        *flags = 0;
        *gp_seq = 0;
@@ -587,20 +591,16 @@ static inline void rcu_gp_set_torture_wait(int duration) { }
 
 #ifdef CONFIG_TINY_SRCU
 
-static inline void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                                          struct srcu_struct *sp, int *flags,
+static inline void srcutorture_get_gp_data(struct srcu_struct *sp, int *flags,
                                           unsigned long *gp_seq)
 {
-       if (test_type != SRCU_FLAVOR)
-               return;
        *flags = 0;
        *gp_seq = sp->srcu_idx;
 }
 
 #elif defined(CONFIG_TREE_SRCU)
 
-void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                            struct srcu_struct *sp, int *flags,
+void srcutorture_get_gp_data(struct srcu_struct *sp, int *flags,
                             unsigned long *gp_seq);
 
 #endif
index 45d6b4c3d199c13481b281360c2f50d75e600cef..807fbf6123a779062e0f4039e591d159752949a6 100644 (file)
@@ -381,6 +381,9 @@ struct rcu_torture_ops {
        void (*gp_kthread_dbg)(void);
        bool (*check_boost_failed)(unsigned long gp_state, int *cpup);
        int (*stall_dur)(void);
+       void (*get_gp_data)(int *flags, unsigned long *gp_seq);
+       void (*gp_slow_register)(atomic_t *rgssp);
+       void (*gp_slow_unregister)(atomic_t *rgssp);
        long cbflood_max;
        int irq_capable;
        int can_boost;
@@ -461,12 +464,13 @@ rcu_torture_pipe_update_one(struct rcu_torture *rp)
                WRITE_ONCE(rp->rtort_chkp, NULL);
                smp_store_release(&rtrcp->rtc_ready, 1); // Pair with smp_load_acquire().
        }
-       i = READ_ONCE(rp->rtort_pipe_count);
+       i = rp->rtort_pipe_count;
        if (i > RCU_TORTURE_PIPE_LEN)
                i = RCU_TORTURE_PIPE_LEN;
        atomic_inc(&rcu_torture_wcount[i]);
        WRITE_ONCE(rp->rtort_pipe_count, i + 1);
-       if (rp->rtort_pipe_count >= RCU_TORTURE_PIPE_LEN) {
+       ASSERT_EXCLUSIVE_WRITER(rp->rtort_pipe_count);
+       if (i + 1 >= RCU_TORTURE_PIPE_LEN) {
                rp->rtort_mbtest = 0;
                return true;
        }
@@ -564,10 +568,12 @@ static struct rcu_torture_ops rcu_ops = {
        .call                   = call_rcu_hurry,
        .cb_barrier             = rcu_barrier,
        .fqs                    = rcu_force_quiescent_state,
-       .stats                  = NULL,
        .gp_kthread_dbg         = show_rcu_gp_kthreads,
        .check_boost_failed     = rcu_check_boost_fail,
        .stall_dur              = rcu_jiffies_till_stall_check,
+       .get_gp_data            = rcutorture_get_gp_data,
+       .gp_slow_register       = rcu_gp_slow_register,
+       .gp_slow_unregister     = rcu_gp_slow_unregister,
        .irq_capable            = 1,
        .can_boost              = IS_ENABLED(CONFIG_RCU_BOOST),
        .extendables            = RCUTORTURE_MAX_EXTEND,
@@ -611,9 +617,6 @@ static struct rcu_torture_ops rcu_busted_ops = {
        .sync           = synchronize_rcu_busted,
        .exp_sync       = synchronize_rcu_busted,
        .call           = call_rcu_busted,
-       .cb_barrier     = NULL,
-       .fqs            = NULL,
-       .stats          = NULL,
        .irq_capable    = 1,
        .name           = "busted"
 };
@@ -627,6 +630,11 @@ static struct srcu_struct srcu_ctld;
 static struct srcu_struct *srcu_ctlp = &srcu_ctl;
 static struct rcu_torture_ops srcud_ops;
 
+static void srcu_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       srcutorture_get_gp_data(srcu_ctlp, flags, gp_seq);
+}
+
 static int srcu_torture_read_lock(void)
 {
        if (cur_ops == &srcud_ops)
@@ -735,6 +743,7 @@ static struct rcu_torture_ops srcu_ops = {
        .call           = srcu_torture_call,
        .cb_barrier     = srcu_torture_barrier,
        .stats          = srcu_torture_stats,
+       .get_gp_data    = srcu_get_gp_data,
        .cbflood_max    = 50000,
        .irq_capable    = 1,
        .no_pi_lock     = IS_ENABLED(CONFIG_TINY_SRCU),
@@ -773,6 +782,7 @@ static struct rcu_torture_ops srcud_ops = {
        .call           = srcu_torture_call,
        .cb_barrier     = srcu_torture_barrier,
        .stats          = srcu_torture_stats,
+       .get_gp_data    = srcu_get_gp_data,
        .cbflood_max    = 50000,
        .irq_capable    = 1,
        .no_pi_lock     = IS_ENABLED(CONFIG_TINY_SRCU),
@@ -837,8 +847,6 @@ static struct rcu_torture_ops trivial_ops = {
        .get_gp_seq     = rcu_no_completed,
        .sync           = synchronize_rcu_trivial,
        .exp_sync       = synchronize_rcu_trivial,
-       .fqs            = NULL,
-       .stats          = NULL,
        .irq_capable    = 1,
        .name           = "trivial"
 };
@@ -881,8 +889,7 @@ static struct rcu_torture_ops tasks_ops = {
        .call           = call_rcu_tasks,
        .cb_barrier     = rcu_barrier_tasks,
        .gp_kthread_dbg = show_rcu_tasks_classic_gp_kthread,
-       .fqs            = NULL,
-       .stats          = NULL,
+       .get_gp_data    = rcu_tasks_get_gp_data,
        .irq_capable    = 1,
        .slow_gps       = 1,
        .name           = "tasks"
@@ -921,9 +928,8 @@ static struct rcu_torture_ops tasks_rude_ops = {
        .call           = call_rcu_tasks_rude,
        .cb_barrier     = rcu_barrier_tasks_rude,
        .gp_kthread_dbg = show_rcu_tasks_rude_gp_kthread,
+       .get_gp_data    = rcu_tasks_rude_get_gp_data,
        .cbflood_max    = 50000,
-       .fqs            = NULL,
-       .stats          = NULL,
        .irq_capable    = 1,
        .name           = "tasks-rude"
 };
@@ -973,9 +979,8 @@ static struct rcu_torture_ops tasks_tracing_ops = {
        .call           = call_rcu_tasks_trace,
        .cb_barrier     = rcu_barrier_tasks_trace,
        .gp_kthread_dbg = show_rcu_tasks_trace_gp_kthread,
+       .get_gp_data    = rcu_tasks_trace_get_gp_data,
        .cbflood_max    = 50000,
-       .fqs            = NULL,
-       .stats          = NULL,
        .irq_capable    = 1,
        .slow_gps       = 1,
        .name           = "tasks-tracing"
@@ -1399,6 +1404,7 @@ rcu_torture_writer(void *arg)
                if (rp == NULL)
                        continue;
                rp->rtort_pipe_count = 0;
+               ASSERT_EXCLUSIVE_WRITER(rp->rtort_pipe_count);
                rcu_torture_writer_state = RTWS_DELAY;
                udelay(torture_random(&rand) & 0x3ff);
                rcu_torture_writer_state = RTWS_REPLACE;
@@ -1414,6 +1420,7 @@ rcu_torture_writer(void *arg)
                        atomic_inc(&rcu_torture_wcount[i]);
                        WRITE_ONCE(old_rp->rtort_pipe_count,
                                   old_rp->rtort_pipe_count + 1);
+                       ASSERT_EXCLUSIVE_WRITER(old_rp->rtort_pipe_count);
 
                        // Make sure readers block polled grace periods.
                        if (cur_ops->get_gp_state && cur_ops->poll_gp_state) {
@@ -1586,7 +1593,8 @@ rcu_torture_writer(void *arg)
                                if (list_empty(&rcu_tortures[i].rtort_free) &&
                                    rcu_access_pointer(rcu_torture_current) != &rcu_tortures[i]) {
                                        tracing_off();
-                                       show_rcu_gp_kthreads();
+                                       if (cur_ops->gp_kthread_dbg)
+                                               cur_ops->gp_kthread_dbg();
                                        WARN(1, "%s: rtort_pipe_count: %d\n", __func__, rcu_tortures[i].rtort_pipe_count);
                                        rcu_ftrace_dump(DUMP_ALL);
                                }
@@ -1997,7 +2005,8 @@ static bool rcu_torture_one_read(struct torture_random_state *trsp, long myid)
        preempt_disable();
        pipe_count = READ_ONCE(p->rtort_pipe_count);
        if (pipe_count > RCU_TORTURE_PIPE_LEN) {
-               /* Should not happen, but... */
+               // Should not happen in a correct RCU implementation,
+               // happens quite often for torture_type=busted.
                pipe_count = RCU_TORTURE_PIPE_LEN;
        }
        completed = cur_ops->get_gp_seq();
@@ -2259,10 +2268,8 @@ rcu_torture_stats_print(void)
                int __maybe_unused flags = 0;
                unsigned long __maybe_unused gp_seq = 0;
 
-               rcutorture_get_gp_data(cur_ops->ttype,
-                                      &flags, &gp_seq);
-               srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp,
-                                       &flags, &gp_seq);
+               if (cur_ops->get_gp_data)
+                       cur_ops->get_gp_data(&flags, &gp_seq);
                wtp = READ_ONCE(writer_task);
                pr_alert("??? Writer stall state %s(%d) g%lu f%#x ->state %#x cpu %d\n",
                         rcu_torture_writer_state_getname(),
@@ -2486,8 +2493,8 @@ static int rcu_torture_stall(void *args)
                        preempt_disable();
                pr_alert("%s start on CPU %d.\n",
                          __func__, raw_smp_processor_id());
-               while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(),
-                                   stop_at))
+               while (ULONG_CMP_LT((unsigned long)ktime_get_seconds(), stop_at) &&
+                      !kthread_should_stop())
                        if (stall_cpu_block) {
 #ifdef CONFIG_PREEMPTION
                                preempt_schedule();
@@ -2832,13 +2839,14 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp)
 
        if (!torture_must_stop() && !READ_ONCE(rcu_fwd_emergency_stop) &&
            !shutdown_time_arrived()) {
-               WARN_ON(n_max_gps < MIN_FWD_CBS_LAUNDERED);
-               pr_alert("%s Duration %lu barrier: %lu pending %ld n_launders: %ld n_launders_sa: %ld n_max_gps: %ld n_max_cbs: %ld cver %ld gps %ld\n",
+               if (WARN_ON(n_max_gps < MIN_FWD_CBS_LAUNDERED) && cur_ops->gp_kthread_dbg)
+                       cur_ops->gp_kthread_dbg();
+               pr_alert("%s Duration %lu barrier: %lu pending %ld n_launders: %ld n_launders_sa: %ld n_max_gps: %ld n_max_cbs: %ld cver %ld gps %ld #online %u\n",
                         __func__,
                         stoppedat - rfp->rcu_fwd_startat, jiffies - stoppedat,
                         n_launders + n_max_cbs - n_launders_cb_snap,
                         n_launders, n_launders_sa,
-                        n_max_gps, n_max_cbs, cver, gps);
+                        n_max_gps, n_max_cbs, cver, gps, num_online_cpus());
                atomic_long_add(n_max_cbs, &rcu_fwd_max_cbs);
                mutex_lock(&rcu_fwd_mutex); // Serialize histograms.
                rcu_torture_fwd_cb_hist(rfp);
@@ -3040,11 +3048,12 @@ static void rcu_torture_barrier_cbf(struct rcu_head *rcu)
 }
 
 /* IPI handler to get callback posted on desired CPU, if online. */
-static void rcu_torture_barrier1cb(void *rcu_void)
+static int rcu_torture_barrier1cb(void *rcu_void)
 {
        struct rcu_head *rhp = rcu_void;
 
        cur_ops->call(rhp, rcu_torture_barrier_cbf);
+       return 0;
 }
 
 /* kthread function to register callbacks used to test RCU barriers. */
@@ -3070,11 +3079,9 @@ static int rcu_torture_barrier_cbs(void *arg)
                 * The above smp_load_acquire() ensures barrier_phase load
                 * is ordered before the following ->call().
                 */
-               if (smp_call_function_single(myid, rcu_torture_barrier1cb,
-                                            &rcu, 1)) {
-                       // IPI failed, so use direct call from current CPU.
+               if (smp_call_on_cpu(myid, rcu_torture_barrier1cb, &rcu, 1))
                        cur_ops->call(&rcu, rcu_torture_barrier_cbf);
-               }
+
                if (atomic_dec_and_test(&barrier_cbs_count))
                        wake_up(&barrier_wq);
        } while (!torture_must_stop());
@@ -3340,12 +3347,12 @@ rcu_torture_cleanup(void)
                        pr_info("%s: Invoking %pS().\n", __func__, cur_ops->cb_barrier);
                        cur_ops->cb_barrier();
                }
-               rcu_gp_slow_unregister(NULL);
+               if (cur_ops->gp_slow_unregister)
+                       cur_ops->gp_slow_unregister(NULL);
                return;
        }
        if (!cur_ops) {
                torture_cleanup_end();
-               rcu_gp_slow_unregister(NULL);
                return;
        }
 
@@ -3384,8 +3391,8 @@ rcu_torture_cleanup(void)
                fakewriter_tasks = NULL;
        }
 
-       rcutorture_get_gp_data(cur_ops->ttype, &flags, &gp_seq);
-       srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp, &flags, &gp_seq);
+       if (cur_ops->get_gp_data)
+               cur_ops->get_gp_data(&flags, &gp_seq);
        pr_alert("%s:  End-test grace-period state: g%ld f%#x total-gps=%ld\n",
                 cur_ops->name, (long)gp_seq, flags,
                 rcutorture_seq_diff(gp_seq, start_gp_seq));
@@ -3444,7 +3451,8 @@ rcu_torture_cleanup(void)
        else
                rcu_torture_print_module_parms(cur_ops, "End of test: SUCCESS");
        torture_cleanup_end();
-       rcu_gp_slow_unregister(&rcu_fwd_cb_nodelay);
+       if (cur_ops->gp_slow_unregister)
+               cur_ops->gp_slow_unregister(NULL);
 }
 
 #ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
@@ -3756,8 +3764,8 @@ rcu_torture_init(void)
                        nrealreaders = 1;
        }
        rcu_torture_print_module_parms(cur_ops, "Start of test");
-       rcutorture_get_gp_data(cur_ops->ttype, &flags, &gp_seq);
-       srcutorture_get_gp_data(cur_ops->ttype, srcu_ctlp, &flags, &gp_seq);
+       if (cur_ops->get_gp_data)
+               cur_ops->get_gp_data(&flags, &gp_seq);
        start_gp_seq = gp_seq;
        pr_alert("%s:  Start-test grace-period state: g%ld f%#x\n",
                 cur_ops->name, (long)gp_seq, flags);
@@ -3926,7 +3934,8 @@ rcu_torture_init(void)
        if (object_debug)
                rcu_test_debug_objects();
        torture_init_end();
-       rcu_gp_slow_register(&rcu_fwd_cb_nodelay);
+       if (cur_ops->gp_slow_register && !WARN_ON_ONCE(!cur_ops->gp_slow_unregister))
+               cur_ops->gp_slow_register(&rcu_fwd_cb_nodelay);
        return 0;
 
 unwind:
index c38e5933a5d6937ce148d586f4023cd17e5bad30..5afd5cf494dba32a6e98e9cd376c362248a2c285 100644 (file)
@@ -96,9 +96,12 @@ EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
  */
 void __srcu_read_unlock(struct srcu_struct *ssp, int idx)
 {
-       int newval = READ_ONCE(ssp->srcu_lock_nesting[idx]) - 1;
+       int newval;
 
+       preempt_disable();  // Needed for PREEMPT_AUTO
+       newval = READ_ONCE(ssp->srcu_lock_nesting[idx]) - 1;
        WRITE_ONCE(ssp->srcu_lock_nesting[idx], newval);
+       preempt_enable();
        if (!newval && READ_ONCE(ssp->srcu_gp_waiting) && in_task())
                swake_up_one(&ssp->srcu_wq);
 }
@@ -117,8 +120,11 @@ void srcu_drive_gp(struct work_struct *wp)
        struct srcu_struct *ssp;
 
        ssp = container_of(wp, struct srcu_struct, srcu_work);
-       if (ssp->srcu_gp_running || ULONG_CMP_GE(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max)))
+       preempt_disable();  // Needed for PREEMPT_AUTO
+       if (ssp->srcu_gp_running || ULONG_CMP_GE(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max))) {
                return; /* Already running or nothing to do. */
+               preempt_enable();
+       }
 
        /* Remove recently arrived callbacks and wait for readers. */
        WRITE_ONCE(ssp->srcu_gp_running, true);
@@ -130,9 +136,12 @@ void srcu_drive_gp(struct work_struct *wp)
        idx = (ssp->srcu_idx & 0x2) / 2;
        WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
        WRITE_ONCE(ssp->srcu_gp_waiting, true);  /* srcu_read_unlock() wakes! */
+       preempt_enable();
        swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx]));
+       preempt_disable();  // Needed for PREEMPT_AUTO
        WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */
        WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
+       preempt_enable();
 
        /* Invoke the callbacks we removed above. */
        while (lh) {
@@ -150,8 +159,11 @@ void srcu_drive_gp(struct work_struct *wp)
         * at interrupt level, but the ->srcu_gp_running checks will
         * straighten that out.
         */
+       preempt_disable();  // Needed for PREEMPT_AUTO
        WRITE_ONCE(ssp->srcu_gp_running, false);
-       if (ULONG_CMP_LT(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max)))
+       idx = ULONG_CMP_LT(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max));
+       preempt_enable();
+       if (idx)
                schedule_work(&ssp->srcu_work);
 }
 EXPORT_SYMBOL_GPL(srcu_drive_gp);
@@ -160,9 +172,12 @@ static void srcu_gp_start_if_needed(struct srcu_struct *ssp)
 {
        unsigned long cookie;
 
+       preempt_disable();  // Needed for PREEMPT_AUTO
        cookie = get_state_synchronize_srcu(ssp);
-       if (ULONG_CMP_GE(READ_ONCE(ssp->srcu_idx_max), cookie))
+       if (ULONG_CMP_GE(READ_ONCE(ssp->srcu_idx_max), cookie)) {
+               preempt_enable();
                return;
+       }
        WRITE_ONCE(ssp->srcu_idx_max, cookie);
        if (!READ_ONCE(ssp->srcu_gp_running)) {
                if (likely(srcu_init_done))
@@ -170,6 +185,7 @@ static void srcu_gp_start_if_needed(struct srcu_struct *ssp)
                else if (list_empty(&ssp->srcu_work.entry))
                        list_add(&ssp->srcu_work.entry, &srcu_boot_list);
        }
+       preempt_enable();
 }
 
 /*
@@ -183,11 +199,13 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *rhp,
 
        rhp->func = func;
        rhp->next = NULL;
+       preempt_disable();  // Needed for PREEMPT_AUTO
        local_irq_save(flags);
        *ssp->srcu_cb_tail = rhp;
        ssp->srcu_cb_tail = &rhp->next;
        local_irq_restore(flags);
        srcu_gp_start_if_needed(ssp);
+       preempt_enable();
 }
 EXPORT_SYMBOL_GPL(call_srcu);
 
@@ -241,9 +259,12 @@ EXPORT_SYMBOL_GPL(get_state_synchronize_srcu);
  */
 unsigned long start_poll_synchronize_srcu(struct srcu_struct *ssp)
 {
-       unsigned long ret = get_state_synchronize_srcu(ssp);
+       unsigned long ret;
 
+       preempt_disable();  // Needed for PREEMPT_AUTO
+       ret = get_state_synchronize_srcu(ssp);
        srcu_gp_start_if_needed(ssp);
+       preempt_enable();
        return ret;
 }
 EXPORT_SYMBOL_GPL(start_poll_synchronize_srcu);
index e4d673fc30f42f9c1278e2c5ee07d1ee894706f3..bc4b58b0204e982e5d412b6afc0cbb91a38dc903 100644 (file)
@@ -1826,12 +1826,9 @@ static void process_srcu(struct work_struct *work)
        srcu_reschedule(ssp, curdelay);
 }
 
-void srcutorture_get_gp_data(enum rcutorture_type test_type,
-                            struct srcu_struct *ssp, int *flags,
+void srcutorture_get_gp_data(struct srcu_struct *ssp, int *flags,
                             unsigned long *gp_seq)
 {
-       if (test_type != SRCU_FLAVOR)
-               return;
        *flags = 0;
        *gp_seq = rcu_seq_current(&ssp->srcu_sup->srcu_gp_seq);
 }
index 86df878a2fee8b0b78718d8158c23bbb8137fb6f..6c2bd9001adcdbede753450918e416b9bd4db5e1 100644 (file)
@@ -122,7 +122,7 @@ void rcu_sync_enter(struct rcu_sync *rsp)
                 * we are called at early boot time but this shouldn't happen.
                 */
        }
-       rsp->gp_count++;
+       WRITE_ONCE(rsp->gp_count, rsp->gp_count + 1);
        spin_unlock_irq(&rsp->rss_lock);
 
        if (gp_state == GP_IDLE) {
@@ -151,11 +151,15 @@ void rcu_sync_enter(struct rcu_sync *rsp)
  */
 void rcu_sync_exit(struct rcu_sync *rsp)
 {
+       int gpc;
+
        WARN_ON_ONCE(READ_ONCE(rsp->gp_state) == GP_IDLE);
        WARN_ON_ONCE(READ_ONCE(rsp->gp_count) == 0);
 
        spin_lock_irq(&rsp->rss_lock);
-       if (!--rsp->gp_count) {
+       gpc = rsp->gp_count - 1;
+       WRITE_ONCE(rsp->gp_count, gpc);
+       if (!gpc) {
                if (rsp->gp_state == GP_PASSED) {
                        WRITE_ONCE(rsp->gp_state, GP_EXIT);
                        rcu_sync_call(rsp);
index 147b5945d67a046dd568e6df586881f8c1a0c25f..e1bf33018e6d5d2af139330f02510c10742fdd83 100644 (file)
@@ -74,6 +74,7 @@ struct rcu_tasks_percpu {
  * @holdouts_func: This flavor's holdout-list scan function (optional).
  * @postgp_func: This flavor's post-grace-period function (optional).
  * @call_func: This flavor's call_rcu()-equivalent function.
+ * @wait_state: Task state for synchronous grace-period waits (default TASK_UNINTERRUPTIBLE).
  * @rtpcpu: This flavor's rcu_tasks_percpu structure.
  * @percpu_enqueue_shift: Shift down CPU ID this much when enqueuing callbacks.
  * @percpu_enqueue_lim: Number of per-CPU callback queues in use for enqueuing.
@@ -107,6 +108,7 @@ struct rcu_tasks {
        holdouts_func_t holdouts_func;
        postgp_func_t postgp_func;
        call_rcu_func_t call_func;
+       unsigned int wait_state;
        struct rcu_tasks_percpu __percpu *rtpcpu;
        int percpu_enqueue_shift;
        int percpu_enqueue_lim;
@@ -134,6 +136,7 @@ static struct rcu_tasks rt_name =                                                   \
        .tasks_gp_mutex = __MUTEX_INITIALIZER(rt_name.tasks_gp_mutex),                  \
        .gp_func = gp,                                                                  \
        .call_func = call,                                                              \
+       .wait_state = TASK_UNINTERRUPTIBLE,                                             \
        .rtpcpu = &rt_name ## __percpu,                                                 \
        .lazy_jiffies = DIV_ROUND_UP(HZ, 4),                                            \
        .name = n,                                                                      \
@@ -147,7 +150,7 @@ static struct rcu_tasks rt_name =                                                   \
 
 #ifdef CONFIG_TASKS_RCU
 
-/* Report delay in synchronize_srcu() completion in rcu_tasks_postscan(). */
+/* Report delay of scan exiting tasklist in rcu_tasks_postscan(). */
 static void tasks_rcu_exit_srcu_stall(struct timer_list *unused);
 static DEFINE_TIMER(tasks_rcu_exit_srcu_stall_timer, tasks_rcu_exit_srcu_stall);
 #endif
@@ -638,7 +641,7 @@ static void synchronize_rcu_tasks_generic(struct rcu_tasks *rtp)
 
        // If the grace-period kthread is running, use it.
        if (READ_ONCE(rtp->kthread_ptr)) {
-               wait_rcu_gp(rtp->call_func);
+               wait_rcu_gp_state(rtp->wait_state, rtp->call_func);
                return;
        }
        rcu_tasks_one_gp(rtp, true);
@@ -1160,6 +1163,7 @@ static int __init rcu_spawn_tasks_kthread(void)
        rcu_tasks.postscan_func = rcu_tasks_postscan;
        rcu_tasks.holdouts_func = check_all_holdout_tasks;
        rcu_tasks.postgp_func = rcu_tasks_postgp;
+       rcu_tasks.wait_state = TASK_IDLE;
        rcu_spawn_tasks_kthread_generic(&rcu_tasks);
        return 0;
 }
@@ -1178,6 +1182,13 @@ struct task_struct *get_rcu_tasks_gp_kthread(void)
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_gp_kthread);
 
+void rcu_tasks_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_get_gp_data);
+
 /*
  * Protect against tasklist scan blind spot while the task is exiting and
  * may be removed from the tasklist.  Do this by adding the task to yet
@@ -1199,8 +1210,7 @@ void exit_tasks_rcu_start(void)
        rtpcp = this_cpu_ptr(rcu_tasks.rtpcpu);
        t->rcu_tasks_exit_cpu = smp_processor_id();
        raw_spin_lock_irqsave_rcu_node(rtpcp, flags);
-       if (!rtpcp->rtp_exit_list.next)
-               INIT_LIST_HEAD(&rtpcp->rtp_exit_list);
+       WARN_ON_ONCE(!rtpcp->rtp_exit_list.next);
        list_add(&t->rcu_tasks_exit_list, &rtpcp->rtp_exit_list);
        raw_spin_unlock_irqrestore_rcu_node(rtpcp, flags);
        preempt_enable();
@@ -1358,6 +1368,13 @@ struct task_struct *get_rcu_tasks_rude_gp_kthread(void)
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_rude_gp_kthread);
 
+void rcu_tasks_rude_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks_rude.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_rude_get_gp_data);
+
 #endif /* #ifdef CONFIG_TASKS_RUDE_RCU */
 
 ////////////////////////////////////////////////////////////////////////
@@ -1457,6 +1474,7 @@ static void rcu_st_need_qs(struct task_struct *t, u8 v)
 /*
  * Do a cmpxchg() on ->trc_reader_special.b.need_qs, allowing for
  * the four-byte operand-size restriction of some platforms.
+ *
  * Returns the old value, which is often ignored.
  */
 u8 rcu_trc_cmpxchg_need_qs(struct task_struct *t, u8 old, u8 new)
@@ -1468,7 +1486,14 @@ u8 rcu_trc_cmpxchg_need_qs(struct task_struct *t, u8 old, u8 new)
        if (trs_old.b.need_qs != old)
                return trs_old.b.need_qs;
        trs_new.b.need_qs = new;
-       ret.s = cmpxchg(&t->trc_reader_special.s, trs_old.s, trs_new.s);
+
+       // Although cmpxchg() appears to KCSAN to update all four bytes,
+       // only the .b.need_qs byte actually changes.
+       instrument_atomic_read_write(&t->trc_reader_special.b.need_qs,
+                                    sizeof(t->trc_reader_special.b.need_qs));
+       // Avoid false-positive KCSAN failures.
+       ret.s = data_race(cmpxchg(&t->trc_reader_special.s, trs_old.s, trs_new.s));
+
        return ret.b.need_qs;
 }
 EXPORT_SYMBOL_GPL(rcu_trc_cmpxchg_need_qs);
@@ -1994,7 +2019,7 @@ void show_rcu_tasks_trace_gp_kthread(void)
 {
        char buf[64];
 
-       sprintf(buf, "N%lu h:%lu/%lu/%lu",
+       snprintf(buf, sizeof(buf), "N%lu h:%lu/%lu/%lu",
                data_race(n_trc_holdouts),
                data_race(n_heavy_reader_ofl_updates),
                data_race(n_heavy_reader_updates),
@@ -2010,6 +2035,13 @@ struct task_struct *get_rcu_tasks_trace_gp_kthread(void)
 }
 EXPORT_SYMBOL_GPL(get_rcu_tasks_trace_gp_kthread);
 
+void rcu_tasks_trace_get_gp_data(int *flags, unsigned long *gp_seq)
+{
+       *flags = 0;
+       *gp_seq = rcu_seq_current(&rcu_tasks_trace.tasks_gp_seq);
+}
+EXPORT_SYMBOL_GPL(rcu_tasks_trace_get_gp_data);
+
 #else /* #ifdef CONFIG_TASKS_TRACE_RCU */
 static void exit_tasks_rcu_finish_trace(struct task_struct *t) { }
 #endif /* #else #ifdef CONFIG_TASKS_TRACE_RCU */
index 705c0d16850aa28db4e0ec7d26d10204e1ed24ce..4402d6f5f85778b46e332485b1a80628e100cf46 100644 (file)
@@ -130,9 +130,7 @@ static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused
                next = list->next;
                prefetch(next);
                debug_rcu_head_unqueue(list);
-               local_bh_disable();
                rcu_reclaim_tiny(list);
-               local_bh_enable();
                list = next;
        }
 }
@@ -155,7 +153,9 @@ void synchronize_rcu(void)
                         lock_is_held(&rcu_lock_map) ||
                         lock_is_held(&rcu_sched_lock_map),
                         "Illegal synchronize_rcu() in RCU read-side critical section");
+       preempt_disable();
        WRITE_ONCE(rcu_ctrlblk.gp_seq, rcu_ctrlblk.gp_seq + 2);
+       preempt_enable();
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
index d9642dd06c2535d9a59682e9b9416d980bd6703c..28c7031711a3fe9604c75272227bf1e6fb0979b8 100644 (file)
@@ -75,6 +75,7 @@
 #define MODULE_PARAM_PREFIX "rcutree."
 
 /* Data structures. */
+static void rcu_sr_normal_gp_cleanup_work(struct work_struct *);
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rcu_data, rcu_data) = {
        .gpwrap = true,
@@ -93,6 +94,8 @@ static struct rcu_state rcu_state = {
        .exp_mutex = __MUTEX_INITIALIZER(rcu_state.exp_mutex),
        .exp_wake_mutex = __MUTEX_INITIALIZER(rcu_state.exp_wake_mutex),
        .ofl_lock = __ARCH_SPIN_LOCK_UNLOCKED,
+       .srs_cleanup_work = __WORK_INITIALIZER(rcu_state.srs_cleanup_work,
+               rcu_sr_normal_gp_cleanup_work),
 };
 
 /* Dump rcu_node combining tree at boot to verify correct setup. */
@@ -240,8 +243,36 @@ static long rcu_get_n_cbs_cpu(int cpu)
        return 0;
 }
 
+/**
+ * rcu_softirq_qs - Provide a set of RCU quiescent states in softirq processing
+ *
+ * Mark a quiescent state for RCU, Tasks RCU, and Tasks Trace RCU.
+ * This is a special-purpose function to be used in the softirq
+ * infrastructure and perhaps the occasional long-running softirq
+ * handler.
+ *
+ * Note that from RCU's viewpoint, a call to rcu_softirq_qs() is
+ * equivalent to momentarily completely enabling preemption.  For
+ * example, given this code::
+ *
+ *     local_bh_disable();
+ *     do_something();
+ *     rcu_softirq_qs();  // A
+ *     do_something_else();
+ *     local_bh_enable();  // B
+ *
+ * A call to synchronize_rcu() that began concurrently with the
+ * call to do_something() would be guaranteed to wait only until
+ * execution reached statement A.  Without that rcu_softirq_qs(),
+ * that same synchronize_rcu() would instead be guaranteed to wait
+ * until execution reached statement B.
+ */
 void rcu_softirq_qs(void)
 {
+       RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) ||
+                        lock_is_held(&rcu_lock_map) ||
+                        lock_is_held(&rcu_sched_lock_map),
+                        "Illegal rcu_softirq_qs() in RCU read-side critical section");
        rcu_qs();
        rcu_preempt_deferred_qs(current);
        rcu_tasks_qs(current, false);
@@ -508,17 +539,10 @@ static struct rcu_node *rcu_get_root(void)
 /*
  * Send along grace-period-related data for rcutorture diagnostics.
  */
-void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags,
-                           unsigned long *gp_seq)
+void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq)
 {
-       switch (test_type) {
-       case RCU_FLAVOR:
-               *flags = READ_ONCE(rcu_state.gp_flags);
-               *gp_seq = rcu_seq_current(&rcu_state.gp_seq);
-               break;
-       default:
-               break;
-       }
+       *flags = READ_ONCE(rcu_state.gp_flags);
+       *gp_seq = rcu_seq_current(&rcu_state.gp_seq);
 }
 EXPORT_SYMBOL_GPL(rcutorture_get_gp_data);
 
@@ -813,8 +837,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
                                __func__, rnp1->grplo, rnp1->grphi, rnp1->qsmask, rnp1->qsmaskinit, rnp1->qsmaskinitnext, rnp1->rcu_gp_init_mask);
                pr_info("%s %d: %c online: %ld(%d) offline: %ld(%d)\n",
                        __func__, rdp->cpu, ".o"[rcu_rdp_cpu_online(rdp)],
-                       (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_flags,
-                       (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_flags);
+                       (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_state,
+                       (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_state);
                return 1; /* Break things loose after complaining. */
        }
 
@@ -1422,6 +1446,305 @@ static void rcu_poll_gp_seq_end_unlocked(unsigned long *snap)
                raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
 }
 
+/*
+ * There is a single llist, which is used for handling
+ * synchronize_rcu() users' enqueued rcu_synchronize nodes.
+ * Within this llist, there are two tail pointers:
+ *
+ * wait tail: Tracks the set of nodes, which need to
+ *            wait for the current GP to complete.
+ * done tail: Tracks the set of nodes, for which grace
+ *            period has elapsed. These nodes processing
+ *            will be done as part of the cleanup work
+ *            execution by a kworker.
+ *
+ * At every grace period init, a new wait node is added
+ * to the llist. This wait node is used as wait tail
+ * for this new grace period. Given that there are a fixed
+ * number of wait nodes, if all wait nodes are in use
+ * (which can happen when kworker callback processing
+ * is delayed) and additional grace period is requested.
+ * This means, a system is slow in processing callbacks.
+ *
+ * TODO: If a slow processing is detected, a first node
+ * in the llist should be used as a wait-tail for this
+ * grace period, therefore users which should wait due
+ * to a slow process are handled by _this_ grace period
+ * and not next.
+ *
+ * Below is an illustration of how the done and wait
+ * tail pointers move from one set of rcu_synchronize nodes
+ * to the other, as grace periods start and finish and
+ * nodes are processed by kworker.
+ *
+ *
+ * a. Initial llist callbacks list:
+ *
+ * +----------+           +--------+          +-------+
+ * |          |           |        |          |       |
+ * |   head   |---------> |   cb2  |--------->| cb1   |
+ * |          |           |        |          |       |
+ * +----------+           +--------+          +-------+
+ *
+ *
+ *
+ * b. New GP1 Start:
+ *
+ *                    WAIT TAIL
+ *                      |
+ *                      |
+ *                      v
+ * +----------+     +--------+      +--------+        +-------+
+ * |          |     |        |      |        |        |       |
+ * |   head   ------> wait   |------>   cb2  |------> |  cb1  |
+ * |          |     | head1  |      |        |        |       |
+ * +----------+     +--------+      +--------+        +-------+
+ *
+ *
+ *
+ * c. GP completion:
+ *
+ * WAIT_TAIL == DONE_TAIL
+ *
+ *                   DONE TAIL
+ *                     |
+ *                     |
+ *                     v
+ * +----------+     +--------+      +--------+        +-------+
+ * |          |     |        |      |        |        |       |
+ * |   head   ------> wait   |------>   cb2  |------> |  cb1  |
+ * |          |     | head1  |      |        |        |       |
+ * +----------+     +--------+      +--------+        +-------+
+ *
+ *
+ *
+ * d. New callbacks and GP2 start:
+ *
+ *                    WAIT TAIL                          DONE TAIL
+ *                      |                                 |
+ *                      |                                 |
+ *                      v                                 v
+ * +----------+     +------+    +------+    +------+    +-----+    +-----+    +-----+
+ * |          |     |      |    |      |    |      |    |     |    |     |    |     |
+ * |   head   ------> wait |--->|  cb4 |--->| cb3  |--->|wait |--->| cb2 |--->| cb1 |
+ * |          |     | head2|    |      |    |      |    |head1|    |     |    |     |
+ * +----------+     +------+    +------+    +------+    +-----+    +-----+    +-----+
+ *
+ *
+ *
+ * e. GP2 completion:
+ *
+ * WAIT_TAIL == DONE_TAIL
+ *                   DONE TAIL
+ *                      |
+ *                      |
+ *                      v
+ * +----------+     +------+    +------+    +------+    +-----+    +-----+    +-----+
+ * |          |     |      |    |      |    |      |    |     |    |     |    |     |
+ * |   head   ------> wait |--->|  cb4 |--->| cb3  |--->|wait |--->| cb2 |--->| cb1 |
+ * |          |     | head2|    |      |    |      |    |head1|    |     |    |     |
+ * +----------+     +------+    +------+    +------+    +-----+    +-----+    +-----+
+ *
+ *
+ * While the llist state transitions from d to e, a kworker
+ * can start executing rcu_sr_normal_gp_cleanup_work() and
+ * can observe either the old done tail (@c) or the new
+ * done tail (@e). So, done tail updates and reads need
+ * to use the rel-acq semantics. If the concurrent kworker
+ * observes the old done tail, the newly queued work
+ * execution will process the updated done tail. If the
+ * concurrent kworker observes the new done tail, then
+ * the newly queued work will skip processing the done
+ * tail, as workqueue semantics guarantees that the new
+ * work is executed only after the previous one completes.
+ *
+ * f. kworker callbacks processing complete:
+ *
+ *
+ *                   DONE TAIL
+ *                     |
+ *                     |
+ *                     v
+ * +----------+     +--------+
+ * |          |     |        |
+ * |   head   ------> wait   |
+ * |          |     | head2  |
+ * +----------+     +--------+
+ *
+ */
+static bool rcu_sr_is_wait_head(struct llist_node *node)
+{
+       return &(rcu_state.srs_wait_nodes)[0].node <= node &&
+               node <= &(rcu_state.srs_wait_nodes)[SR_NORMAL_GP_WAIT_HEAD_MAX - 1].node;
+}
+
+static struct llist_node *rcu_sr_get_wait_head(void)
+{
+       struct sr_wait_node *sr_wn;
+       int i;
+
+       for (i = 0; i < SR_NORMAL_GP_WAIT_HEAD_MAX; i++) {
+               sr_wn = &(rcu_state.srs_wait_nodes)[i];
+
+               if (!atomic_cmpxchg_acquire(&sr_wn->inuse, 0, 1))
+                       return &sr_wn->node;
+       }
+
+       return NULL;
+}
+
+static void rcu_sr_put_wait_head(struct llist_node *node)
+{
+       struct sr_wait_node *sr_wn = container_of(node, struct sr_wait_node, node);
+
+       atomic_set_release(&sr_wn->inuse, 0);
+}
+
+/* Disabled by default. */
+static int rcu_normal_wake_from_gp;
+module_param(rcu_normal_wake_from_gp, int, 0644);
+static struct workqueue_struct *sync_wq;
+
+static void rcu_sr_normal_complete(struct llist_node *node)
+{
+       struct rcu_synchronize *rs = container_of(
+               (struct rcu_head *) node, struct rcu_synchronize, head);
+       unsigned long oldstate = (unsigned long) rs->head.func;
+
+       WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&
+               !poll_state_synchronize_rcu(oldstate),
+               "A full grace period is not passed yet: %lu",
+               rcu_seq_diff(get_state_synchronize_rcu(), oldstate));
+
+       /* Finally. */
+       complete(&rs->completion);
+}
+
+static void rcu_sr_normal_gp_cleanup_work(struct work_struct *work)
+{
+       struct llist_node *done, *rcu, *next, *head;
+
+       /*
+        * This work execution can potentially execute
+        * while a new done tail is being updated by
+        * grace period kthread in rcu_sr_normal_gp_cleanup().
+        * So, read and updates of done tail need to
+        * follow acq-rel semantics.
+        *
+        * Given that wq semantics guarantees that a single work
+        * cannot execute concurrently by multiple kworkers,
+        * the done tail list manipulations are protected here.
+        */
+       done = smp_load_acquire(&rcu_state.srs_done_tail);
+       if (!done)
+               return;
+
+       WARN_ON_ONCE(!rcu_sr_is_wait_head(done));
+       head = done->next;
+       done->next = NULL;
+
+       /*
+        * The dummy node, which is pointed to by the
+        * done tail which is acq-read above is not removed
+        * here.  This allows lockless additions of new
+        * rcu_synchronize nodes in rcu_sr_normal_add_req(),
+        * while the cleanup work executes. The dummy
+        * nodes is removed, in next round of cleanup
+        * work execution.
+        */
+       llist_for_each_safe(rcu, next, head) {
+               if (!rcu_sr_is_wait_head(rcu)) {
+                       rcu_sr_normal_complete(rcu);
+                       continue;
+               }
+
+               rcu_sr_put_wait_head(rcu);
+       }
+}
+
+/*
+ * Helper function for rcu_gp_cleanup().
+ */
+static void rcu_sr_normal_gp_cleanup(void)
+{
+       struct llist_node *wait_tail, *next, *rcu;
+       int done = 0;
+
+       wait_tail = rcu_state.srs_wait_tail;
+       if (wait_tail == NULL)
+               return;
+
+       rcu_state.srs_wait_tail = NULL;
+       ASSERT_EXCLUSIVE_WRITER(rcu_state.srs_wait_tail);
+       WARN_ON_ONCE(!rcu_sr_is_wait_head(wait_tail));
+
+       /*
+        * Process (a) and (d) cases. See an illustration.
+        */
+       llist_for_each_safe(rcu, next, wait_tail->next) {
+               if (rcu_sr_is_wait_head(rcu))
+                       break;
+
+               rcu_sr_normal_complete(rcu);
+               // It can be last, update a next on this step.
+               wait_tail->next = next;
+
+               if (++done == SR_MAX_USERS_WAKE_FROM_GP)
+                       break;
+       }
+
+       // concurrent sr_normal_gp_cleanup work might observe this update.
+       smp_store_release(&rcu_state.srs_done_tail, wait_tail);
+       ASSERT_EXCLUSIVE_WRITER(rcu_state.srs_done_tail);
+
+       /*
+        * We schedule a work in order to perform a final processing
+        * of outstanding users(if still left) and releasing wait-heads
+        * added by rcu_sr_normal_gp_init() call.
+        */
+       queue_work(sync_wq, &rcu_state.srs_cleanup_work);
+}
+
+/*
+ * Helper function for rcu_gp_init().
+ */
+static bool rcu_sr_normal_gp_init(void)
+{
+       struct llist_node *first;
+       struct llist_node *wait_head;
+       bool start_new_poll = false;
+
+       first = READ_ONCE(rcu_state.srs_next.first);
+       if (!first || rcu_sr_is_wait_head(first))
+               return start_new_poll;
+
+       wait_head = rcu_sr_get_wait_head();
+       if (!wait_head) {
+               // Kick another GP to retry.
+               start_new_poll = true;
+               return start_new_poll;
+       }
+
+       /* Inject a wait-dummy-node. */
+       llist_add(wait_head, &rcu_state.srs_next);
+
+       /*
+        * A waiting list of rcu_synchronize nodes should be empty on
+        * this step, since a GP-kthread, rcu_gp_init() -> gp_cleanup(),
+        * rolls it over. If not, it is a BUG, warn a user.
+        */
+       WARN_ON_ONCE(rcu_state.srs_wait_tail != NULL);
+       rcu_state.srs_wait_tail = wait_head;
+       ASSERT_EXCLUSIVE_WRITER(rcu_state.srs_wait_tail);
+
+       return start_new_poll;
+}
+
+static void rcu_sr_normal_add_req(struct rcu_synchronize *rs)
+{
+       llist_add((struct llist_node *) &rs->head, &rcu_state.srs_next);
+}
+
 /*
  * Initialize a new grace period.  Return false if no grace period required.
  */
@@ -1432,10 +1755,11 @@ static noinline_for_stack bool rcu_gp_init(void)
        unsigned long mask;
        struct rcu_data *rdp;
        struct rcu_node *rnp = rcu_get_root();
+       bool start_new_poll;
 
        WRITE_ONCE(rcu_state.gp_activity, jiffies);
        raw_spin_lock_irq_rcu_node(rnp);
-       if (!READ_ONCE(rcu_state.gp_flags)) {
+       if (!rcu_state.gp_flags) {
                /* Spurious wakeup, tell caller to go back to sleep.  */
                raw_spin_unlock_irq_rcu_node(rnp);
                return false;
@@ -1456,10 +1780,24 @@ static noinline_for_stack bool rcu_gp_init(void)
        /* Record GP times before starting GP, hence rcu_seq_start(). */
        rcu_seq_start(&rcu_state.gp_seq);
        ASSERT_EXCLUSIVE_WRITER(rcu_state.gp_seq);
+       start_new_poll = rcu_sr_normal_gp_init();
        trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("start"));
        rcu_poll_gp_seq_start(&rcu_state.gp_seq_polled_snap);
        raw_spin_unlock_irq_rcu_node(rnp);
 
+       /*
+        * The "start_new_poll" is set to true, only when this GP is not able
+        * to handle anything and there are outstanding users. It happens when
+        * the rcu_sr_normal_gp_init() function was not able to insert a dummy
+        * separator to the llist, because there were no left any dummy-nodes.
+        *
+        * Number of dummy-nodes is fixed, it could be that we are run out of
+        * them, if so we start a new pool request to repeat a try. It is rare
+        * and it means that a system is doing a slow processing of callbacks.
+        */
+       if (start_new_poll)
+               (void) start_poll_synchronize_rcu();
+
        /*
         * Apply per-leaf buffered online and offline operations to
         * the rcu_node tree. Note that this new grace period need not
@@ -1620,8 +1958,7 @@ static void rcu_gp_fqs(bool first_time)
        /* Clear flag to prevent immediate re-entry. */
        if (READ_ONCE(rcu_state.gp_flags) & RCU_GP_FLAG_FQS) {
                raw_spin_lock_irq_rcu_node(rnp);
-               WRITE_ONCE(rcu_state.gp_flags,
-                          READ_ONCE(rcu_state.gp_flags) & ~RCU_GP_FLAG_FQS);
+               WRITE_ONCE(rcu_state.gp_flags, rcu_state.gp_flags & ~RCU_GP_FLAG_FQS);
                raw_spin_unlock_irq_rcu_node(rnp);
        }
 }
@@ -1825,6 +2162,9 @@ static noinline void rcu_gp_cleanup(void)
        }
        raw_spin_unlock_irq_rcu_node(rnp);
 
+       // Make synchronize_rcu() users aware of the end of old grace period.
+       rcu_sr_normal_gp_cleanup();
+
        // If strict, make all CPUs aware of the end of the old grace period.
        if (IS_ENABLED(CONFIG_RCU_STRICT_GRACE_PERIOD))
                on_each_cpu(rcu_strict_gp_boundary, NULL, 0);
@@ -1882,8 +2222,7 @@ static void rcu_report_qs_rsp(unsigned long flags)
 {
        raw_lockdep_assert_held_rcu_node(rcu_get_root());
        WARN_ON_ONCE(!rcu_gp_in_progress());
-       WRITE_ONCE(rcu_state.gp_flags,
-                  READ_ONCE(rcu_state.gp_flags) | RCU_GP_FLAG_FQS);
+       WRITE_ONCE(rcu_state.gp_flags, rcu_state.gp_flags | RCU_GP_FLAG_FQS);
        raw_spin_unlock_irqrestore_rcu_node(rcu_get_root(), flags);
        rcu_gp_kthread_wake();
 }
@@ -2398,8 +2737,7 @@ void rcu_force_quiescent_state(void)
                raw_spin_unlock_irqrestore_rcu_node(rnp_old, flags);
                return;  /* Someone beat us to it. */
        }
-       WRITE_ONCE(rcu_state.gp_flags,
-                  READ_ONCE(rcu_state.gp_flags) | RCU_GP_FLAG_FQS);
+       WRITE_ONCE(rcu_state.gp_flags, rcu_state.gp_flags | RCU_GP_FLAG_FQS);
        raw_spin_unlock_irqrestore_rcu_node(rnp_old, flags);
        rcu_gp_kthread_wake();
 }
@@ -3559,6 +3897,43 @@ static int rcu_blocking_is_gp(void)
        return true;
 }
 
+/*
+ * Helper function for the synchronize_rcu() API.
+ */
+static void synchronize_rcu_normal(void)
+{
+       struct rcu_synchronize rs;
+
+       trace_rcu_sr_normal(rcu_state.name, &rs.head, TPS("request"));
+
+       if (!READ_ONCE(rcu_normal_wake_from_gp)) {
+               wait_rcu_gp(call_rcu_hurry);
+               goto trace_complete_out;
+       }
+
+       init_rcu_head_on_stack(&rs.head);
+       init_completion(&rs.completion);
+
+       /*
+        * This code might be preempted, therefore take a GP
+        * snapshot before adding a request.
+        */
+       if (IS_ENABLED(CONFIG_PROVE_RCU))
+               rs.head.func = (void *) get_state_synchronize_rcu();
+
+       rcu_sr_normal_add_req(&rs);
+
+       /* Kick a GP and start waiting. */
+       (void) start_poll_synchronize_rcu();
+
+       /* Now we can wait. */
+       wait_for_completion(&rs.completion);
+       destroy_rcu_head_on_stack(&rs.head);
+
+trace_complete_out:
+       trace_rcu_sr_normal(rcu_state.name, &rs.head, TPS("complete"));
+}
+
 /**
  * synchronize_rcu - wait until a grace period has elapsed.
  *
@@ -3610,7 +3985,7 @@ void synchronize_rcu(void)
                if (rcu_gp_is_expedited())
                        synchronize_rcu_expedited();
                else
-                       wait_rcu_gp(call_rcu_hurry);
+                       synchronize_rcu_normal();
                return;
        }
 
@@ -4303,7 +4678,7 @@ EXPORT_SYMBOL_GPL(rcu_lockdep_current_cpu_online);
 // whether spinlocks may be acquired safely.
 static bool rcu_init_invoked(void)
 {
-       return !!rcu_state.n_online_cpus;
+       return !!READ_ONCE(rcu_state.n_online_cpus);
 }
 
 /*
@@ -4395,9 +4770,9 @@ rcu_boot_init_percpu_data(int cpu)
        WARN_ON_ONCE(rcu_dynticks_in_eqs(rcu_dynticks_snap(cpu)));
        rdp->barrier_seq_snap = rcu_state.barrier_sequence;
        rdp->rcu_ofl_gp_seq = rcu_state.gp_seq;
-       rdp->rcu_ofl_gp_flags = RCU_GP_CLEANED;
+       rdp->rcu_ofl_gp_state = RCU_GP_CLEANED;
        rdp->rcu_onl_gp_seq = rcu_state.gp_seq;
-       rdp->rcu_onl_gp_flags = RCU_GP_CLEANED;
+       rdp->rcu_onl_gp_state = RCU_GP_CLEANED;
        rdp->last_sched_clock = jiffies;
        rdp->cpu = cpu;
        rcu_boot_init_nocb_percpu_data(rdp);
@@ -4513,6 +4888,7 @@ int rcutree_prepare_cpu(unsigned int cpu)
        raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
        rcu_spawn_rnp_kthreads(rnp);
        rcu_spawn_cpu_nocb_kthread(cpu);
+       ASSERT_EXCLUSIVE_WRITER(rcu_state.n_online_cpus);
        WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus + 1);
 
        return 0;
@@ -4656,7 +5032,7 @@ void rcutree_report_cpu_starting(unsigned int cpu)
        ASSERT_EXCLUSIVE_WRITER(rcu_state.ncpus);
        rcu_gpnum_ovf(rnp, rdp); /* Offline-induced counter wrap? */
        rdp->rcu_onl_gp_seq = READ_ONCE(rcu_state.gp_seq);
-       rdp->rcu_onl_gp_flags = READ_ONCE(rcu_state.gp_flags);
+       rdp->rcu_onl_gp_state = READ_ONCE(rcu_state.gp_state);
 
        /* An incoming CPU should never be blocking a grace period. */
        if (WARN_ON_ONCE(rnp->qsmask & mask)) { /* RCU waiting on incoming CPU? */
@@ -4707,7 +5083,7 @@ void rcutree_report_cpu_dead(void)
        arch_spin_lock(&rcu_state.ofl_lock);
        raw_spin_lock_irqsave_rcu_node(rnp, flags); /* Enforce GP memory-order guarantee. */
        rdp->rcu_ofl_gp_seq = READ_ONCE(rcu_state.gp_seq);
-       rdp->rcu_ofl_gp_flags = READ_ONCE(rcu_state.gp_flags);
+       rdp->rcu_ofl_gp_state = READ_ONCE(rcu_state.gp_state);
        if (rnp->qsmask & mask) { /* RCU waiting on outgoing CPU? */
                /* Report quiescent state -before- changing ->qsmaskinitnext! */
                rcu_disable_urgency_upon_qs(rdp);
@@ -4781,6 +5157,7 @@ void rcutree_migrate_callbacks(int cpu)
  */
 int rcutree_dead_cpu(unsigned int cpu)
 {
+       ASSERT_EXCLUSIVE_WRITER(rcu_state.n_online_cpus);
        WRITE_ONCE(rcu_state.n_online_cpus, rcu_state.n_online_cpus - 1);
        // Stop-machine done, so allow nohz_full to disable tick.
        tick_dep_clear(TICK_DEP_BIT_RCU);
@@ -5229,6 +5606,9 @@ void __init rcu_init(void)
        rcu_gp_wq = alloc_workqueue("rcu_gp", WQ_MEM_RECLAIM, 0);
        WARN_ON(!rcu_gp_wq);
 
+       sync_wq = alloc_workqueue("sync_wq", WQ_MEM_RECLAIM, 0);
+       WARN_ON(!sync_wq);
+
        /* Fill in default value for rcutree.qovld boot parameter. */
        /* -After- the rcu_node ->lock fields are initialized! */
        if (qovld < 0)
index df48160b3136dca1b668a3e0d275832ccc273dd3..bae7925c497feecc5116b46b23ac8194e77a66d4 100644 (file)
@@ -273,9 +273,9 @@ struct rcu_data {
        bool rcu_iw_pending;            /* Is ->rcu_iw pending? */
        unsigned long rcu_iw_gp_seq;    /* ->gp_seq associated with ->rcu_iw. */
        unsigned long rcu_ofl_gp_seq;   /* ->gp_seq at last offline. */
-       short rcu_ofl_gp_flags;         /* ->gp_flags at last offline. */
+       short rcu_ofl_gp_state;         /* ->gp_state at last offline. */
        unsigned long rcu_onl_gp_seq;   /* ->gp_seq at last online. */
-       short rcu_onl_gp_flags;         /* ->gp_flags at last online. */
+       short rcu_onl_gp_state;         /* ->gp_state at last online. */
        unsigned long last_fqs_resched; /* Time of last rcu_resched(). */
        unsigned long last_sched_clock; /* Jiffies of last rcu_sched_clock_irq(). */
        struct rcu_snap_record snap_record; /* Snapshot of core stats at half of */
@@ -315,6 +315,19 @@ do {                                                                       \
        __set_current_state(TASK_RUNNING);                              \
 } while (0)
 
+/*
+ * A max threshold for synchronize_rcu() users which are
+ * awaken directly by the rcu_gp_kthread(). Left part is
+ * deferred to the main worker.
+ */
+#define SR_MAX_USERS_WAKE_FROM_GP 5
+#define SR_NORMAL_GP_WAIT_HEAD_MAX 5
+
+struct sr_wait_node {
+       atomic_t inuse;
+       struct llist_node node;
+};
+
 /*
  * RCU global state, including node hierarchy.  This hierarchy is
  * represented in "heap" form in a dense array.  The root (first level)
@@ -400,6 +413,13 @@ struct rcu_state {
                                                /* Synchronize offline with */
                                                /*  GP pre-initialization. */
        int nocb_is_setup;                      /* nocb is setup from boot */
+
+       /* synchronize_rcu() part. */
+       struct llist_head srs_next;     /* request a GP users. */
+       struct llist_node *srs_wait_tail; /* wait for GP users. */
+       struct llist_node *srs_done_tail; /* ready for GP users. */
+       struct sr_wait_node srs_wait_nodes[SR_NORMAL_GP_WAIT_HEAD_MAX];
+       struct work_struct srs_cleanup_work;
 };
 
 /* Values for rcu_state structure's gp_flags field. */
index 6b83537480b12f01c05be827b3eeae87dbb4c6ce..8a1d9c8bd9f7487e7667120d1df9d74d25b34db9 100644 (file)
@@ -930,7 +930,7 @@ void synchronize_rcu_expedited(void)
 
        /* If expedited grace periods are prohibited, fall back to normal. */
        if (rcu_gp_is_normal()) {
-               wait_rcu_gp(call_rcu_hurry);
+               synchronize_rcu_normal();
                return;
        }
 
index 36a8b5dbf5b52ecff9e879f102a53fa6cd264474..340bbefe5f652d99ef87a5db168eb960a8fa5f30 100644 (file)
@@ -805,8 +805,8 @@ dump_blkd_tasks(struct rcu_node *rnp, int ncheck)
                rdp = per_cpu_ptr(&rcu_data, cpu);
                pr_info("\t%d: %c online: %ld(%d) offline: %ld(%d)\n",
                        cpu, ".o"[rcu_rdp_cpu_online(rdp)],
-                       (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_flags,
-                       (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_flags);
+                       (long)rdp->rcu_onl_gp_seq, rdp->rcu_onl_gp_state,
+                       (long)rdp->rcu_ofl_gp_seq, rdp->rcu_ofl_gp_state);
        }
 }
 
index 5d666428546b03ac9e865fbc6e1ae9b1e057100f..460efecd077be13940a94fe5a06197f25e6921a9 100644 (file)
@@ -504,7 +504,8 @@ static void print_cpu_stall_info(int cpu)
                        rcu_dynticks_in_eqs(rcu_dynticks_snap(cpu));
        rcuc_starved = rcu_is_rcuc_kthread_starving(rdp, &j);
        if (rcuc_starved)
-               sprintf(buf, " rcuc=%ld jiffies(starved)", j);
+               // Print signed value, as negative values indicate a probable bug.
+               snprintf(buf, sizeof(buf), " rcuc=%ld jiffies(starved)", j);
        pr_err("\t%d-%c%c%c%c: (%lu %s) idle=%04x/%ld/%#lx softirq=%u/%u fqs=%ld%s%s\n",
               cpu,
               "O."[!!cpu_online(cpu)],
@@ -579,7 +580,7 @@ static void rcu_check_gp_kthread_expired_fqs_timer(void)
                pr_err("%s kthread timer wakeup didn't happen for %ld jiffies! g%ld f%#x %s(%d) ->state=%#x\n",
                       rcu_state.name, (jiffies - jiffies_fqs),
                       (long)rcu_seq_current(&rcu_state.gp_seq),
-                      data_race(rcu_state.gp_flags),
+                      data_race(READ_ONCE(rcu_state.gp_flags)), // Diagnostic read
                       gp_state_getname(RCU_GP_WAIT_FQS), RCU_GP_WAIT_FQS,
                       data_race(READ_ONCE(gpk->__state)));
                pr_err("\tPossible timer handling issue on cpu=%d timer-softirq=%u\n",
@@ -628,7 +629,8 @@ static void print_other_cpu_stall(unsigned long gp_seq, unsigned long gps)
                totqlen += rcu_get_n_cbs_cpu(cpu);
        pr_err("\t(detected by %d, t=%ld jiffies, g=%ld, q=%lu ncpus=%d)\n",
               smp_processor_id(), (long)(jiffies - gps),
-              (long)rcu_seq_current(&rcu_state.gp_seq), totqlen, rcu_state.n_online_cpus);
+              (long)rcu_seq_current(&rcu_state.gp_seq), totqlen,
+              data_race(rcu_state.n_online_cpus)); // Diagnostic read
        if (ndetected) {
                rcu_dump_cpu_stacks();
 
@@ -689,7 +691,8 @@ static void print_cpu_stall(unsigned long gps)
                totqlen += rcu_get_n_cbs_cpu(cpu);
        pr_err("\t(t=%lu jiffies g=%ld q=%lu ncpus=%d)\n",
                jiffies - gps,
-               (long)rcu_seq_current(&rcu_state.gp_seq), totqlen, rcu_state.n_online_cpus);
+               (long)rcu_seq_current(&rcu_state.gp_seq), totqlen,
+               data_race(rcu_state.n_online_cpus)); // Diagnostic read
 
        rcu_check_gp_kthread_expired_fqs_timer();
        rcu_check_gp_kthread_starvation();
index 46aaaa9fe33907b0eddb70e2b1c5d6a2419c13c8..f8436969e0c89e221b6f07743fe845969d2e6fa4 100644 (file)
@@ -408,7 +408,7 @@ void wakeme_after_rcu(struct rcu_head *head)
 }
 EXPORT_SYMBOL_GPL(wakeme_after_rcu);
 
-void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
+void __wait_rcu_gp(bool checktiny, unsigned int state, int n, call_rcu_func_t *crcu_array,
                   struct rcu_synchronize *rs_array)
 {
        int i;
@@ -440,7 +440,7 @@ void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array,
                        if (crcu_array[j] == crcu_array[i])
                                break;
                if (j == i) {
-                       wait_for_completion(&rs_array[i].completion);
+                       wait_for_completion_state(&rs_array[i].completion, state);
                        destroy_rcu_head_on_stack(&rs_array[i].head);
                }
        }
index 03be0d1330a6b22336c91cd4cfeae7fd82838692..c62805dbd6088b3bd63ac07766b92443f35f0e36 100644 (file)
@@ -696,15 +696,21 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq)
  *
  * XXX could add max_slice to the augmented data to track this.
  */
-static void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
+static s64 entity_lag(u64 avruntime, struct sched_entity *se)
 {
-       s64 lag, limit;
+       s64 vlag, limit;
+
+       vlag = avruntime - se->vruntime;
+       limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
 
+       return clamp(vlag, -limit, limit);
+}
+
+static void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se)
+{
        SCHED_WARN_ON(!se->on_rq);
-       lag = avg_vruntime(cfs_rq) - se->vruntime;
 
-       limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se);
-       se->vlag = clamp(lag, -limit, limit);
+       se->vlag = entity_lag(avg_vruntime(cfs_rq), se);
 }
 
 /*
@@ -3676,11 +3682,10 @@ static inline void
 dequeue_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se) { }
 #endif
 
-static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
+static void reweight_eevdf(struct sched_entity *se, u64 avruntime,
                           unsigned long weight)
 {
        unsigned long old_weight = se->load.weight;
-       u64 avruntime = avg_vruntime(cfs_rq);
        s64 vlag, vslice;
 
        /*
@@ -3761,7 +3766,7 @@ static void reweight_eevdf(struct cfs_rq *cfs_rq, struct sched_entity *se,
         *         = V  - vl'
         */
        if (avruntime != se->vruntime) {
-               vlag = (s64)(avruntime - se->vruntime);
+               vlag = entity_lag(avruntime, se);
                vlag = div_s64(vlag * old_weight, weight);
                se->vruntime = avruntime - vlag;
        }
@@ -3787,25 +3792,26 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
                            unsigned long weight)
 {
        bool curr = cfs_rq->curr == se;
+       u64 avruntime;
 
        if (se->on_rq) {
                /* commit outstanding execution time */
-               if (curr)
-                       update_curr(cfs_rq);
-               else
+               update_curr(cfs_rq);
+               avruntime = avg_vruntime(cfs_rq);
+               if (!curr)
                        __dequeue_entity(cfs_rq, se);
                update_load_sub(&cfs_rq->load, se->load.weight);
        }
        dequeue_load_avg(cfs_rq, se);
 
-       if (!se->on_rq) {
+       if (se->on_rq) {
+               reweight_eevdf(se, avruntime, weight);
+       } else {
                /*
                 * Because we keep se->vlag = V - v_i, while: lag_i = w_i*(V - v_i),
                 * we need to scale se->vlag when w_i changes.
                 */
                se->vlag = div_s64(se->vlag * se->load.weight, weight);
-       } else {
-               reweight_eevdf(cfs_rq, se, weight);
        }
 
        update_load_set(&se->load, weight);
index 373d42c707bc5d65d70c18d66e0ffd1621d33f5b..5891e715f00d028b0d2f4fd157e99f319b899a1d 100644 (file)
@@ -46,7 +46,16 @@ int housekeeping_any_cpu(enum hk_type type)
                        if (cpu < nr_cpu_ids)
                                return cpu;
 
-                       return cpumask_any_and(housekeeping.cpumasks[type], cpu_online_mask);
+                       cpu = cpumask_any_and(housekeeping.cpumasks[type], cpu_online_mask);
+                       if (likely(cpu < nr_cpu_ids))
+                               return cpu;
+                       /*
+                        * Unless we have another problem this can only happen
+                        * at boot time before start_secondary() brings the 1st
+                        * housekeeping CPU up.
+                        */
+                       WARN_ON_ONCE(system_state == SYSTEM_RUNNING ||
+                                    type != HK_TYPE_TIMER);
                }
        }
        return smp_processor_id();
@@ -109,6 +118,7 @@ static void __init housekeeping_setup_type(enum hk_type type,
 static int __init housekeeping_setup(char *str, unsigned long flags)
 {
        cpumask_var_t non_housekeeping_mask, housekeeping_staging;
+       unsigned int first_cpu;
        int err = 0;
 
        if ((flags & HK_FLAG_TICK) && !(housekeeping.flags & HK_FLAG_TICK)) {
@@ -129,7 +139,8 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
        cpumask_andnot(housekeeping_staging,
                       cpu_possible_mask, non_housekeeping_mask);
 
-       if (!cpumask_intersects(cpu_present_mask, housekeeping_staging)) {
+       first_cpu = cpumask_first_and(cpu_present_mask, housekeeping_staging);
+       if (first_cpu >= nr_cpu_ids || first_cpu >= setup_max_cpus) {
                __cpumask_set_cpu(smp_processor_id(), housekeeping_staging);
                __cpumask_clear_cpu(smp_processor_id(), non_housekeeping_mask);
                if (!housekeeping.flags) {
@@ -138,6 +149,9 @@ static int __init housekeeping_setup(char *str, unsigned long flags)
                }
        }
 
+       if (cpumask_empty(non_housekeeping_mask))
+               goto free_housekeeping_staging;
+
        if (!housekeeping.flags) {
                /* First setup call ("nohz_full=" or "isolcpus=") */
                enum hk_type type;
index b315b21fb28cd281fc38d1a8a00ed9f9527e2f53..02582017759a2ce3bfb42faf4be904a7b432595b 100644 (file)
@@ -508,7 +508,7 @@ static inline bool lockdep_softirq_start(void) { return false; }
 static inline void lockdep_softirq_end(bool in_hardirq) { }
 #endif
 
-asmlinkage __visible void __softirq_entry __do_softirq(void)
+static void handle_softirqs(bool ksirqd)
 {
        unsigned long end = jiffies + MAX_SOFTIRQ_TIME;
        unsigned long old_flags = current->flags;
@@ -563,8 +563,7 @@ restart:
                pending >>= softirq_bit;
        }
 
-       if (!IS_ENABLED(CONFIG_PREEMPT_RT) &&
-           __this_cpu_read(ksoftirqd) == current)
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT) && ksirqd)
                rcu_softirq_qs();
 
        local_irq_disable();
@@ -584,6 +583,11 @@ restart:
        current_restore_flags(old_flags, PF_MEMALLOC);
 }
 
+asmlinkage __visible void __softirq_entry __do_softirq(void)
+{
+       handle_softirqs(false);
+}
+
 /**
  * irq_enter_rcu - Enter an interrupt context with RCU watching
  */
@@ -921,7 +925,7 @@ static void run_ksoftirqd(unsigned int cpu)
                 * We can safely run softirq on inline stack, as we are not deep
                 * in the task stack here.
                 */
-               __do_softirq();
+               handle_softirqs(true);
                ksoftirqd_run_end();
                cond_resched();
                return;
index ccba875d2234fe582264e7d802dcb62f4864e4f6..84413114db5c5b34e7b11ceaaeb1167a2ad04635 100644 (file)
@@ -1596,7 +1596,7 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node)
 
        } while (i < tmigr_hierarchy_levels);
 
-       do {
+       while (i > 0) {
                group = stack[--i];
 
                if (err < 0) {
@@ -1645,7 +1645,7 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node)
                                tmigr_connect_child_parent(child, group);
                        }
                }
-       } while (i > 0);
+       }
 
        kfree(stack);
 
index 47345bf1d4a9f7e850db213999c62ecb02f8fea0..b3d7f62ac58115aaea3b006fb9cfe0cc81b03785 100644 (file)
@@ -163,7 +163,7 @@ config TRACING
        select BINARY_PRINTF
        select EVENT_TRACING
        select TRACE_CLOCK
-       select TASKS_RCU if PREEMPTION
+       select NEED_TASKS_RCU
 
 config GENERIC_TRACER
        bool
@@ -204,7 +204,7 @@ config FUNCTION_TRACER
        select GENERIC_TRACER
        select CONTEXT_SWITCH_TRACER
        select GLOB
-       select TASKS_RCU if PREEMPTION
+       select NEED_TASKS_RCU
        select TASKS_RUDE_RCU
        help
          Enable the kernel to trace every kernel function. This is done
index da1710499698b0ed56ea89183d18befda56c0243..6c96b30f3d63b0a681de16deb50a6a96f6d0c61d 100644 (file)
@@ -3157,8 +3157,7 @@ out:
                 * synchronize_rcu_tasks() will wait for those tasks to
                 * execute and either schedule voluntarily or enter user space.
                 */
-               if (IS_ENABLED(CONFIG_PREEMPTION))
-                       synchronize_rcu_tasks();
+               synchronize_rcu_tasks();
 
                ftrace_trampoline_free(ops);
        }
index 52f75c36bbca4922bec786815bb70ff409f62a61..6ef29eba90ceb7e06774171d79c7ea244ecaa72a 100644 (file)
@@ -2552,6 +2552,14 @@ static int event_callback(const char *name, umode_t *mode, void **data,
        return 0;
 }
 
+/* The file is incremented on creation and freeing the enable file decrements it */
+static void event_release(const char *name, void *data)
+{
+       struct trace_event_file *file = data;
+
+       event_file_put(file);
+}
+
 static int
 event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
 {
@@ -2566,6 +2574,7 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
                {
                        .name           = "enable",
                        .callback       = event_callback,
+                       .release        = event_release,
                },
                {
                        .name           = "filter",
@@ -2634,6 +2643,9 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
                return ret;
        }
 
+       /* Gets decremented on freeing of the "enable" file */
+       event_file_get(file);
+
        return 0;
 }
 
index dfe3ee6035ecc74da70ebd8104d23f1ef2a25cde..42bc0f3622263b60618fbc8fd39f2f3beedf44a3 100644 (file)
@@ -1466,7 +1466,7 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
                parg->fmt = kmalloc(len, GFP_KERNEL);
                if (!parg->fmt) {
                        ret = -ENOMEM;
-                       goto out;
+                       goto fail;
                }
                snprintf(parg->fmt, len, "%s[%d]", parg->type->fmttype,
                         parg->count);
index 0066c8f6c15442641889c87995410ac82d078423..d2dbe099286b95ca5f0b745e577af0e6ed297062 100644 (file)
@@ -1277,8 +1277,12 @@ static bool kick_pool(struct worker_pool *pool)
            !cpumask_test_cpu(p->wake_cpu, pool->attrs->__pod_cpumask)) {
                struct work_struct *work = list_first_entry(&pool->worklist,
                                                struct work_struct, entry);
-               p->wake_cpu = cpumask_any_distribute(pool->attrs->__pod_cpumask);
-               get_work_pwq(work)->stats[PWQ_STAT_REPATRIATED]++;
+               int wake_cpu = cpumask_any_and_distribute(pool->attrs->__pod_cpumask,
+                                                         cpu_online_mask);
+               if (wake_cpu < nr_cpu_ids) {
+                       p->wake_cpu = wake_cpu;
+                       get_work_pwq(work)->stats[PWQ_STAT_REPATRIATED]++;
+               }
        }
 #endif
        wake_up_process(p);
@@ -1594,6 +1598,15 @@ static void wq_update_node_max_active(struct workqueue_struct *wq, int off_cpu)
        if (off_cpu >= 0)
                total_cpus--;
 
+       /* If all CPUs of the wq get offline, use the default values */
+       if (unlikely(!total_cpus)) {
+               for_each_node(node)
+                       wq_node_nr_active(wq, node)->max = min_active;
+
+               wq_node_nr_active(wq, NUMA_NO_NODE)->max = max_active;
+               return;
+       }
+
        for_each_node(node) {
                int node_cpus;
 
@@ -1606,7 +1619,7 @@ static void wq_update_node_max_active(struct workqueue_struct *wq, int off_cpu)
                              min_active, max_active);
        }
 
-       wq_node_nr_active(wq, NUMA_NO_NODE)->max = min_active;
+       wq_node_nr_active(wq, NUMA_NO_NODE)->max = max_active;
 }
 
 /**
index c63a5fbf1f1c2b45b67603886ef9e6f07510f61d..291185f54ee4c217d04b8040b339dc1ad47f9cf6 100644 (file)
@@ -375,7 +375,7 @@ config DEBUG_INFO_SPLIT
          Incompatible with older versions of ccache.
 
 config DEBUG_INFO_BTF
-       bool "Generate BTF typeinfo"
+       bool "Generate BTF type information"
        depends on !DEBUG_INFO_SPLIT && !DEBUG_INFO_REDUCED
        depends on !GCC_PLUGIN_RANDSTRUCT || COMPILE_TEST
        depends on BPF_SYSCALL
@@ -408,7 +408,8 @@ config PAHOLE_HAS_LANG_EXCLUDE
          using DEBUG_INFO_BTF_MODULES.
 
 config DEBUG_INFO_BTF_MODULES
-       def_bool y
+       bool "Generate BTF type information for kernel modules"
+       default y
        depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF
        help
          Generate compact split BTF type information for kernel modules.
index ffc6b2341b45a52a8ba1820d5ff9718cfe05a4a1..cc3d52fdb477d994320d4fa57cf3737fef03db36 100644 (file)
@@ -236,6 +236,7 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 lib-$(CONFIG_GENERIC_BUG) += bug.o
 
 obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
+obj-$(CONFIG_ARCH_NEED_CMPXCHG_1_EMU) += cmpxchg-emu.o
 
 obj-$(CONFIG_DYNAMIC_DEBUG_CORE) += dynamic_debug.o
 #ensure exported functions have prototypes
diff --git a/lib/cmpxchg-emu.c b/lib/cmpxchg-emu.c
new file mode 100644 (file)
index 0000000..27f6f97
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Emulated 1-byte cmpxchg operation for architectures lacking direct
+ * support for this size.  This is implemented in terms of 4-byte cmpxchg
+ * operations.
+ *
+ * Copyright (C) 2024 Paul E. McKenney.
+ */
+
+#include <linux/types.h>
+#include <linux/export.h>
+#include <linux/instrumented.h>
+#include <linux/atomic.h>
+#include <linux/panic.h>
+#include <linux/bug.h>
+#include <asm-generic/rwonce.h>
+#include <linux/cmpxchg-emu.h>
+
+union u8_32 {
+       u8 b[4];
+       u32 w;
+};
+
+/* Emulate one-byte cmpxchg() in terms of 4-byte cmpxchg. */
+uintptr_t cmpxchg_emu_u8(volatile u8 *p, uintptr_t old, uintptr_t new)
+{
+       u32 *p32 = (u32 *)(((uintptr_t)p) & ~0x3);
+       int i = ((uintptr_t)p) & 0x3;
+       union u8_32 old32;
+       union u8_32 new32;
+       u32 ret;
+
+       ret = READ_ONCE(*p32);
+       do {
+               old32.w = ret;
+               if (old32.b[i] != old)
+                       return old32.b[i];
+               new32.w = old32.w;
+               new32.b[i] = new;
+               instrument_atomic_read_write(p, 1);
+               ret = data_race(cmpxchg(p32, old32.w, new32.w)); // Overridden above.
+       } while (ret != old32.w);
+       return old;
+}
+EXPORT_SYMBOL_GPL(cmpxchg_emu_u8);
index 45436bfc6dffe1db285db1b9a6912997edbafb1a..b01253cac70a74998e8c90ae7e203d12a2649170 100644 (file)
@@ -8,6 +8,11 @@ config CRYPTO_LIB_UTILS
 config CRYPTO_LIB_AES
        tristate
 
+config CRYPTO_LIB_AESCFB
+       tristate
+       select CRYPTO_LIB_AES
+       select CRYPTO_LIB_UTILS
+
 config CRYPTO_LIB_AESGCM
        tristate
        select CRYPTO_LIB_AES
index 8d1446c2be7193dfbdd879cbb799b9dde58bc375..969baab8c805f22da29700d35c906f17f8c5771c 100644 (file)
@@ -10,6 +10,9 @@ obj-$(CONFIG_CRYPTO_LIB_CHACHA_GENERIC)               += libchacha.o
 obj-$(CONFIG_CRYPTO_LIB_AES)                   += libaes.o
 libaes-y                                       := aes.o
 
+obj-$(CONFIG_CRYPTO_LIB_AESCFB)                        += libaescfb.o
+libaescfb-y                                    := aescfb.o
+
 obj-$(CONFIG_CRYPTO_LIB_AESGCM)                        += libaesgcm.o
 libaesgcm-y                                    := aesgcm.o
 
diff --git a/lib/crypto/aescfb.c b/lib/crypto/aescfb.c
new file mode 100644 (file)
index 0000000..749dc12
--- /dev/null
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Minimal library implementation of AES in CFB mode
+ *
+ * Copyright 2023 Google LLC
+ */
+
+#include <linux/module.h>
+
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+
+#include <asm/irqflags.h>
+
+static void aescfb_encrypt_block(const struct crypto_aes_ctx *ctx, void *dst,
+                                const void *src)
+{
+       unsigned long flags;
+
+       /*
+        * In AES-CFB, the AES encryption operates on known 'plaintext' (the IV
+        * and ciphertext), making it susceptible to timing attacks on the
+        * encryption key. The AES library already mitigates this risk to some
+        * extent by pulling the entire S-box into the caches before doing any
+        * substitutions, but this strategy is more effective when running with
+        * interrupts disabled.
+        */
+       local_irq_save(flags);
+       aes_encrypt(ctx, dst, src);
+       local_irq_restore(flags);
+}
+
+/**
+ * aescfb_encrypt - Perform AES-CFB encryption on a block of data
+ *
+ * @ctx:       The AES-CFB key schedule
+ * @dst:       Pointer to the ciphertext output buffer
+ * @src:       Pointer the plaintext (may equal @dst for encryption in place)
+ * @len:       The size in bytes of the plaintext and ciphertext.
+ * @iv:                The initialization vector (IV) to use for this block of data
+ */
+void aescfb_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src,
+                   int len, const u8 iv[AES_BLOCK_SIZE])
+{
+       u8 ks[AES_BLOCK_SIZE];
+       const u8 *v = iv;
+
+       while (len > 0) {
+               aescfb_encrypt_block(ctx, ks, v);
+               crypto_xor_cpy(dst, src, ks, min(len, AES_BLOCK_SIZE));
+               v = dst;
+
+               dst += AES_BLOCK_SIZE;
+               src += AES_BLOCK_SIZE;
+               len -= AES_BLOCK_SIZE;
+       }
+
+       memzero_explicit(ks, sizeof(ks));
+}
+EXPORT_SYMBOL(aescfb_encrypt);
+
+/**
+ * aescfb_decrypt - Perform AES-CFB decryption on a block of data
+ *
+ * @ctx:       The AES-CFB key schedule
+ * @dst:       Pointer to the plaintext output buffer
+ * @src:       Pointer the ciphertext (may equal @dst for decryption in place)
+ * @len:       The size in bytes of the plaintext and ciphertext.
+ * @iv:                The initialization vector (IV) to use for this block of data
+ */
+void aescfb_decrypt(const struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src,
+                   int len, const u8 iv[AES_BLOCK_SIZE])
+{
+       u8 ks[2][AES_BLOCK_SIZE];
+
+       aescfb_encrypt_block(ctx, ks[0], iv);
+
+       for (int i = 0; len > 0; i ^= 1) {
+               if (len > AES_BLOCK_SIZE)
+                       /*
+                        * Generate the keystream for the next block before
+                        * performing the XOR, as that may update in place and
+                        * overwrite the ciphertext.
+                        */
+                       aescfb_encrypt_block(ctx, ks[!i], src);
+
+               crypto_xor_cpy(dst, src, ks[i], min(len, AES_BLOCK_SIZE));
+
+               dst += AES_BLOCK_SIZE;
+               src += AES_BLOCK_SIZE;
+               len -= AES_BLOCK_SIZE;
+       }
+
+       memzero_explicit(ks, sizeof(ks));
+}
+EXPORT_SYMBOL(aescfb_decrypt);
+
+MODULE_DESCRIPTION("Generic AES-CFB library");
+MODULE_AUTHOR("Ard Biesheuvel <ardb@kernel.org>");
+MODULE_LICENSE("GPL");
+
+#ifndef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
+
+/*
+ * Test code below. Vectors taken from crypto/testmgr.h
+ */
+
+static struct {
+       u8      ptext[64];
+       u8      ctext[64];
+
+       u8      key[AES_MAX_KEY_SIZE];
+       u8      iv[AES_BLOCK_SIZE];
+
+       int     klen;
+       int     len;
+} const aescfb_tv[] __initconst = {
+       { /* From NIST SP800-38A */
+               .key    = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+                         "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+               .klen   = 16,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ptext  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ctext  = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20"
+                         "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a"
+                         "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f"
+                         "\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"
+                         "\x26\x75\x1f\x67\xa3\xcb\xb1\x40"
+                         "\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf"
+                         "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e"
+                         "\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6",
+               .len    = 64,
+       }, {
+               .key    = "\x8e\x73\xb0\xf7\xda\x0e\x64\x52"
+                         "\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+                         "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+               .klen   = 24,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ptext  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ctext  = "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab"
+                         "\x34\xc2\x59\x09\xc9\x9a\x41\x74"
+                         "\x67\xce\x7f\x7f\x81\x17\x36\x21"
+                         "\x96\x1a\x2b\x70\x17\x1d\x3d\x7a"
+                         "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1"
+                         "\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9"
+                         "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0"
+                         "\x42\xae\x8f\xba\x58\x4b\x09\xff",
+               .len    = 64,
+       }, {
+               .key    = "\x60\x3d\xeb\x10\x15\xca\x71\xbe"
+                         "\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+                         "\x1f\x35\x2c\x07\x3b\x61\x08\xd7"
+                         "\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+               .klen   = 32,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ptext  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+                         "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+                         "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+                         "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+                         "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+                         "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+               .ctext  = "\xdc\x7e\x84\xbf\xda\x79\x16\x4b"
+                         "\x7e\xcd\x84\x86\x98\x5d\x38\x60"
+                         "\x39\xff\xed\x14\x3b\x28\xb1\xc8"
+                         "\x32\x11\x3c\x63\x31\xe5\x40\x7b"
+                         "\xdf\x10\x13\x24\x15\xe5\x4b\x92"
+                         "\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9"
+                         "\x75\xa3\x85\x74\x1a\xb9\xce\xf8"
+                         "\x20\x31\x62\x3d\x55\xb1\xe4\x71",
+               .len    = 64,
+       }, { /* > 16 bytes, not a multiple of 16 bytes */
+               .key    = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+                         "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+               .klen   = 16,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ptext  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+                         "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+                         "\xae",
+               .ctext  = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20"
+                         "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a"
+                         "\xc8",
+               .len    = 17,
+       }, { /* < 16 bytes */
+               .key    = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+                         "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+               .klen   = 16,
+               .iv     = "\x00\x01\x02\x03\x04\x05\x06\x07"
+                         "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+               .ptext  = "\x6b\xc1\xbe\xe2\x2e\x40\x9f",
+               .ctext  = "\x3b\x3f\xd9\x2e\xb7\x2d\xad",
+               .len    = 7,
+       },
+};
+
+static int __init libaescfb_init(void)
+{
+       for (int i = 0; i < ARRAY_SIZE(aescfb_tv); i++) {
+               struct crypto_aes_ctx ctx;
+               u8 buf[64];
+
+               if (aes_expandkey(&ctx, aescfb_tv[i].key, aescfb_tv[i].klen)) {
+                       pr_err("aes_expandkey() failed on vector %d\n", i);
+                       return -ENODEV;
+               }
+
+               aescfb_encrypt(&ctx, buf, aescfb_tv[i].ptext, aescfb_tv[i].len,
+                              aescfb_tv[i].iv);
+               if (memcmp(buf, aescfb_tv[i].ctext, aescfb_tv[i].len)) {
+                       pr_err("aescfb_encrypt() #1 failed on vector %d\n", i);
+                       return -ENODEV;
+               }
+
+               /* decrypt in place */
+               aescfb_decrypt(&ctx, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv);
+               if (memcmp(buf, aescfb_tv[i].ptext, aescfb_tv[i].len)) {
+                       pr_err("aescfb_decrypt() failed on vector %d\n", i);
+                       return -ENODEV;
+               }
+
+               /* encrypt in place */
+               aescfb_encrypt(&ctx, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv);
+               if (memcmp(buf, aescfb_tv[i].ctext, aescfb_tv[i].len)) {
+                       pr_err("aescfb_encrypt() #2 failed on vector %d\n", i);
+
+                       return -ENODEV;
+               }
+
+       }
+       return 0;
+}
+module_init(libaescfb_init);
+
+static void __exit libaescfb_exit(void)
+{
+}
+module_exit(libaescfb_exit);
+#endif
index c78f335fa98137664745e6593c98b707a528bf34..f2c5e7910bb19122f29d93b0c1e896638738b1a3 100644 (file)
@@ -302,7 +302,11 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords)
                } else {
                        for (end = buf; *end && !isspace(*end); end++)
                                ;
-                       BUG_ON(end == buf);
+                       if (end == buf) {
+                               pr_err("parse err after word:%d=%s\n", nwords,
+                                      nwords ? words[nwords - 1] : "<none>");
+                               return -EINVAL;
+                       }
                }
 
                /* `buf' is start of word, `end' is one past its end */
index 55e1b35bf877ea529d4f278692c57f46a259d568..2d7d27e6ae3c698daa75538941a9eacc9b04cb10 100644 (file)
@@ -5109,18 +5109,18 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
        if (size == 0 || max - min < size - 1)
                return -EINVAL;
 
-       if (mas_is_start(mas)) {
+       if (mas_is_start(mas))
                mas_start(mas);
-               mas->offset = mas_data_end(mas);
-       } else if (mas->offset >= 2) {
-               mas->offset -= 2;
-       } else if (!mas_rewind_node(mas)) {
+       else if ((mas->offset < 2) && (!mas_rewind_node(mas)))
                return -EBUSY;
-       }
 
-       /* Empty set. */
-       if (mas_is_none(mas) || mas_is_ptr(mas))
+       if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))
                return mas_sparse_area(mas, min, max, size, false);
+       else if (mas->offset >= 2)
+               mas->offset -= 2;
+       else
+               mas->offset = mas_data_end(mas);
+
 
        /* The start of the window can only be within these values. */
        mas->index = min;
index 68b45c82c37a6981bb72cc79ab4c4fcac8e2e489..7bc2220fea805855fadd0a1ed347ea2b9195e9e9 100644 (file)
@@ -1124,7 +1124,7 @@ static ssize_t extract_user_to_sg(struct iov_iter *iter,
        do {
                res = iov_iter_extract_pages(iter, &pages, maxsize, sg_max,
                                             extraction_flags, &off);
-               if (res < 0)
+               if (res <= 0)
                        goto failed;
 
                len = res;
index d4a3730b08fa7e175a8bad91a8722d476b9e05be..4ce9604388069dd927e367630e18cfce32010f41 100644 (file)
@@ -55,7 +55,7 @@ static void test_next_pointer(struct kunit *test)
 
        ptr_addr = (unsigned long *)(p + s->offset);
        tmp = *ptr_addr;
-       p[s->offset] = 0x12;
+       p[s->offset] = ~p[s->offset];
 
        /*
         * Expecting three errors.
index ebe2af2e072db390b2c65e149969c65544476e16..928fc20337e65834a9f0aa414b306a08d6891f4e 100644 (file)
@@ -744,15 +744,20 @@ static noinline void check_xa_multi_store_adv_add(struct xarray *xa,
 
        do {
                xas_lock_irq(&xas);
-
                xas_store(&xas, p);
-               XA_BUG_ON(xa, xas_error(&xas));
-               XA_BUG_ON(xa, xa_load(xa, index) != p);
-
                xas_unlock_irq(&xas);
+               /*
+                * In our selftest case the only failure we can expect is for
+                * there not to be enough memory as we're not mimicking the
+                * entire page cache, so verify that's the only error we can run
+                * into here. The xas_nomem() which follows will ensure to fix
+                * that condition for us so to chug on on the loop.
+                */
+               XA_BUG_ON(xa, xas_error(&xas) && xas_error(&xas) != -ENOMEM);
        } while (xas_nomem(&xas, GFP_KERNEL));
 
        XA_BUG_ON(xa, xas_error(&xas));
+       XA_BUG_ON(xa, xa_load(xa, index) != p);
 }
 
 /* mimics page_cache_delete() */
@@ -1783,9 +1788,11 @@ static void check_split_1(struct xarray *xa, unsigned long index,
                                unsigned int order, unsigned int new_order)
 {
        XA_STATE_ORDER(xas, xa, index, new_order);
-       unsigned int i;
+       unsigned int i, found;
+       void *entry;
 
        xa_store_order(xa, index, order, xa, GFP_KERNEL);
+       xa_set_mark(xa, index, XA_MARK_1);
 
        xas_split_alloc(&xas, xa, order, GFP_KERNEL);
        xas_lock(&xas);
@@ -1802,6 +1809,16 @@ static void check_split_1(struct xarray *xa, unsigned long index,
        xa_set_mark(xa, index, XA_MARK_0);
        XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
 
+       xas_set_order(&xas, index, 0);
+       found = 0;
+       rcu_read_lock();
+       xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_1) {
+               found++;
+               XA_BUG_ON(xa, xa_is_internal(entry));
+       }
+       rcu_read_unlock();
+       XA_BUG_ON(xa, found != 1 << (order - new_order));
+
        xa_destroy(xa);
 }
 
index 39f07bfc4dccacd4da23f76bc0c553815728bee5..5e7d6334d70d7d1e16291a15fd2f5a45a83f81b9 100644 (file)
@@ -969,8 +969,22 @@ static unsigned int node_get_marks(struct xa_node *node, unsigned int offset)
        return marks;
 }
 
+static inline void node_mark_slots(struct xa_node *node, unsigned int sibs,
+               xa_mark_t mark)
+{
+       int i;
+
+       if (sibs == 0)
+               node_mark_all(node, mark);
+       else {
+               for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1)
+                       node_set_mark(node, i, mark);
+       }
+}
+
 static void node_set_marks(struct xa_node *node, unsigned int offset,
-                       struct xa_node *child, unsigned int marks)
+                       struct xa_node *child, unsigned int sibs,
+                       unsigned int marks)
 {
        xa_mark_t mark = XA_MARK_0;
 
@@ -978,7 +992,7 @@ static void node_set_marks(struct xa_node *node, unsigned int offset,
                if (marks & (1 << (__force unsigned int)mark)) {
                        node_set_mark(node, offset, mark);
                        if (child)
-                               node_mark_all(child, mark);
+                               node_mark_slots(child, sibs, mark);
                }
                if (mark == XA_MARK_MAX)
                        break;
@@ -1077,7 +1091,8 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
                        child->nr_values = xa_is_value(entry) ?
                                        XA_CHUNK_SIZE : 0;
                        RCU_INIT_POINTER(child->parent, node);
-                       node_set_marks(node, offset, child, marks);
+                       node_set_marks(node, offset, child, xas->xa_sibs,
+                                       marks);
                        rcu_assign_pointer(node->slots[offset],
                                        xa_mk_node(child));
                        if (xa_is_value(curr))
@@ -1086,7 +1101,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
                } else {
                        unsigned int canon = offset - xas->xa_sibs;
 
-                       node_set_marks(node, canon, NULL, marks);
+                       node_set_marks(node, canon, NULL, 0, marks);
                        rcu_assign_pointer(node->slots[canon], entry);
                        while (offset > canon)
                                rcu_assign_pointer(node->slots[offset--],
index b1448aa81e15f48d7a2c14d18b666485635f2df1..f30a18a0e37dafb1812936731299c3b16a036664 100644 (file)
@@ -333,10 +333,9 @@ config SHUFFLE_PAGE_ALLOCATOR
 
          While the randomization improves cache utilization it may
          negatively impact workloads on platforms without a cache. For
-         this reason, by default, the randomization is enabled only
-         after runtime detection of a direct-mapped memory-side-cache.
-         Otherwise, the randomization may be force enabled with the
-         'page_alloc.shuffle' kernel command line parameter.
+         this reason, by default, the randomization is not enabled even
+         if SHUFFLE_PAGE_ALLOCATOR=y. The randomization may be force enabled
+         with the 'page_alloc.shuffle' kernel command line parameter.
 
          Say Y if unsure.
 
index 30de18c4fd28a907184695e3cf0f60079e956d89..1d6b3a3690777b058251035609976bfd4d3299f5 100644 (file)
@@ -1540,7 +1540,7 @@ EXPORT_SYMBOL(folio_end_private_2);
  * folio_wait_private_2 - Wait for PG_private_2 to be cleared on a folio.
  * @folio: The folio to wait on.
  *
- * Wait for PG_private_2 (aka PG_fscache) to be cleared on a folio.
+ * Wait for PG_private_2 to be cleared on a folio.
  */
 void folio_wait_private_2(struct folio *folio)
 {
@@ -1553,8 +1553,8 @@ EXPORT_SYMBOL(folio_wait_private_2);
  * folio_wait_private_2_killable - Wait for PG_private_2 to be cleared on a folio.
  * @folio: The folio to wait on.
  *
- * Wait for PG_private_2 (aka PG_fscache) to be cleared on a folio or until a
- * fatal signal is received by the calling task.
+ * Wait for PG_private_2 to be cleared on a folio or until a fatal signal is
+ * received by the calling task.
  *
  * Return:
  * - 0 if successful.
@@ -4134,6 +4134,60 @@ bool filemap_release_folio(struct folio *folio, gfp_t gfp)
 }
 EXPORT_SYMBOL(filemap_release_folio);
 
+/**
+ * filemap_invalidate_inode - Invalidate/forcibly write back a range of an inode's pagecache
+ * @inode: The inode to flush
+ * @flush: Set to write back rather than simply invalidate.
+ * @start: First byte to in range.
+ * @end: Last byte in range (inclusive), or LLONG_MAX for everything from start
+ *       onwards.
+ *
+ * Invalidate all the folios on an inode that contribute to the specified
+ * range, possibly writing them back first.  Whilst the operation is
+ * undertaken, the invalidate lock is held to prevent new folios from being
+ * installed.
+ */
+int filemap_invalidate_inode(struct inode *inode, bool flush,
+                            loff_t start, loff_t end)
+{
+       struct address_space *mapping = inode->i_mapping;
+       pgoff_t first = start >> PAGE_SHIFT;
+       pgoff_t last = end >> PAGE_SHIFT;
+       pgoff_t nr = end == LLONG_MAX ? ULONG_MAX : last - first + 1;
+
+       if (!mapping || !mapping->nrpages || end < start)
+               goto out;
+
+       /* Prevent new folios from being added to the inode. */
+       filemap_invalidate_lock(mapping);
+
+       if (!mapping->nrpages)
+               goto unlock;
+
+       unmap_mapping_pages(mapping, first, nr, false);
+
+       /* Write back the data if we're asked to. */
+       if (flush) {
+               struct writeback_control wbc = {
+                       .sync_mode      = WB_SYNC_ALL,
+                       .nr_to_write    = LONG_MAX,
+                       .range_start    = start,
+                       .range_end      = end,
+               };
+
+               filemap_fdatawrite_wbc(mapping, &wbc);
+       }
+
+       /* Wait for writeback to complete on all folios and discard. */
+       truncate_inode_pages_range(mapping, start, end);
+
+unlock:
+       filemap_invalidate_unlock(mapping);
+out:
+       return filemap_check_errors(mapping);
+}
+EXPORT_SYMBOL_GPL(filemap_invalidate_inode);
+
 #ifdef CONFIG_CACHESTAT_SYSCALL
 /**
  * filemap_cachestat() - compute the page cache statistics of a mapping
index 6dbda99a47da1c332682c95c03bf3ce6c74f562f..3490af70f2592e05eb5740f5b6e9427c5ca3942f 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1294,7 +1294,9 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
                if (!file_mmap_ok(file, inode, pgoff, len))
                        return -EOVERFLOW;
 
-               flags_mask = LEGACY_MAP_MASK | file->f_op->mmap_supported_flags;
+               flags_mask = LEGACY_MAP_MASK;
+               if (file->f_op->fop_flags & FOP_MMAP_SYNC)
+                       flags_mask |= MAP_SYNC;
 
                switch (flags & MAP_TYPE) {
                case MAP_SHARED:
index 3e19b87049db1742dc12c0ce2d246f68e026d012..06fc89d981e8b59cf9ff24727297ab2be46ac632 100644 (file)
@@ -2546,6 +2546,7 @@ done:
        folio_batch_release(&wbc->fbatch);
        return NULL;
 }
+EXPORT_SYMBOL_GPL(writeback_iter);
 
 /**
  * write_cache_pages - walk the list of dirty pages of the given address space and write all of them.
index 742f432e5bf06f560abdc675d658401f76df5237..8eed0f3dc0853c3a694b8169ccee62edef321b43 100644 (file)
@@ -170,7 +170,7 @@ static void add_stack_record_to_list(struct stack_record *stack_record,
 
        /* Filter gfp_mask the same way stackdepot does, for consistency */
        gfp_mask &= ~GFP_ZONEMASK;
-       gfp_mask &= (GFP_ATOMIC | GFP_KERNEL);
+       gfp_mask &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP);
        gfp_mask |= __GFP_NOWARN;
 
        set_current_in_page_owner();
@@ -328,7 +328,7 @@ noinline void __set_page_owner(struct page *page, unsigned short order,
        if (unlikely(!page_ext))
                return;
        __update_page_owner_handle(page_ext, handle, order, gfp_mask, -1,
-                                  current->pid, current->tgid, ts_nsec,
+                                  ts_nsec, current->pid, current->tgid,
                                   current->comm);
        page_ext_put(page_ext);
        inc_stack_record_count(handle, gfp_mask, 1 << order);
index 130c0e7df99f585a5cd8343ad26aa6af7f50cf51..d55138e9560b54782c3a518e1e650e2bfc9b3556 100644 (file)
@@ -490,6 +490,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
        pgoff_t index = readahead_index(ractl);
        pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
        pgoff_t mark = index + ra->size - ra->async_size;
+       unsigned int nofs;
        int err = 0;
        gfp_t gfp = readahead_gfp_mask(mapping);
 
@@ -504,6 +505,8 @@ void page_cache_ra_order(struct readahead_control *ractl,
                new_order = min_t(unsigned int, new_order, ilog2(ra->size));
        }
 
+       /* See comment in page_cache_ra_unbounded() */
+       nofs = memalloc_nofs_save();
        filemap_invalidate_lock_shared(mapping);
        while (index <= limit) {
                unsigned int order = new_order;
@@ -527,6 +530,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
 
        read_pages(ractl);
        filemap_invalidate_unlock_shared(mapping);
+       memalloc_nofs_restore(nofs);
 
        /*
         * If there were already pages in the page cache, then we may have
index 94ab99b6b574a461e34bb875fdec497ad24728ce..1f84a41aeb850ebe4da955f81c044ad11dadaf9b 100644 (file)
@@ -3467,8 +3467,7 @@ static int shmem_rename2(struct mnt_idmap *idmap,
                        return error;
        }
 
-       simple_offset_remove(shmem_get_offset_ctx(old_dir), old_dentry);
-       error = simple_offset_add(shmem_get_offset_ctx(new_dir), old_dentry);
+       error = simple_offset_rename(old_dir, old_dentry, new_dir, new_dentry);
        if (error)
                return error;
 
index d2bc9b191222929b8c99b40c96e3707b8d5e0ecf..78e205b46e19a84765db48fe03fd2204ac8a2f78 100644 (file)
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -496,9 +496,6 @@ struct slabinfo {
 };
 
 void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo);
-void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s);
-ssize_t slabinfo_write(struct file *file, const char __user *buffer,
-                      size_t count, loff_t *ppos);
 
 #ifdef CONFIG_SLUB_DEBUG
 #ifdef CONFIG_SLUB_DEBUG_ON
index f5234672f03ceab3b4c017f3b1acfc53cadb2393..c37f8c41ffb00beb5f51d5ba598fb8d9be4bc735 100644 (file)
@@ -916,22 +916,15 @@ void __init create_kmalloc_caches(void)
         * Including KMALLOC_CGROUP if CONFIG_MEMCG_KMEM defined
         */
        for (type = KMALLOC_NORMAL; type < NR_KMALLOC_TYPES; type++) {
-               for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) {
-                       if (!kmalloc_caches[type][i])
-                               new_kmalloc_cache(i, type);
-
-                       /*
-                        * Caches that are not of the two-to-the-power-of size.
-                        * These have to be created immediately after the
-                        * earlier power of two caches
-                        */
-                       if (KMALLOC_MIN_SIZE <= 32 && i == 6 &&
-                                       !kmalloc_caches[type][1])
-                               new_kmalloc_cache(1, type);
-                       if (KMALLOC_MIN_SIZE <= 64 && i == 7 &&
-                                       !kmalloc_caches[type][2])
-                               new_kmalloc_cache(2, type);
-               }
+               /* Caches that are NOT of the two-to-the-power-of size. */
+               if (KMALLOC_MIN_SIZE <= 32)
+                       new_kmalloc_cache(1, type);
+               if (KMALLOC_MIN_SIZE <= 64)
+                       new_kmalloc_cache(2, type);
+
+               /* Caches that are of the two-to-the-power-of size. */
+               for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++)
+                       new_kmalloc_cache(i, type);
        }
 #ifdef CONFIG_RANDOM_KMALLOC_CACHES
        random_kmalloc_seed = get_random_u64();
@@ -1078,7 +1071,6 @@ static void cache_show(struct kmem_cache *s, struct seq_file *m)
                   sinfo.limit, sinfo.batchcount, sinfo.shared);
        seq_printf(m, " : slabdata %6lu %6lu %6lu",
                   sinfo.active_slabs, sinfo.num_slabs, sinfo.shared_avail);
-       slabinfo_show_stats(m, s);
        seq_putc(m, '\n');
 }
 
@@ -1155,7 +1147,6 @@ static const struct proc_ops slabinfo_proc_ops = {
        .proc_flags     = PROC_ENTRY_PERMANENT,
        .proc_open      = slabinfo_open,
        .proc_read      = seq_read,
-       .proc_write     = slabinfo_write,
        .proc_lseek     = seq_lseek,
        .proc_release   = seq_release,
 };
index 1bb2a93cf7b6a415de2077e8f4e4f7999b85044c..4954999183d58ecba9d7e86f44025131934308f2 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -557,6 +557,26 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
        *(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr);
 }
 
+/*
+ * See comment in calculate_sizes().
+ */
+static inline bool freeptr_outside_object(struct kmem_cache *s)
+{
+       return s->offset >= s->inuse;
+}
+
+/*
+ * Return offset of the end of info block which is inuse + free pointer if
+ * not overlapping with object.
+ */
+static inline unsigned int get_info_end(struct kmem_cache *s)
+{
+       if (freeptr_outside_object(s))
+               return s->inuse + sizeof(void *);
+       else
+               return s->inuse;
+}
+
 /* Loop over all objects in a slab */
 #define for_each_object(__p, __s, __addr, __objects) \
        for (__p = fixup_red_left(__s, __addr); \
@@ -604,11 +624,21 @@ static void slub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects)
        nr_slabs = DIV_ROUND_UP(nr_objects * 2, oo_objects(s->oo));
        s->cpu_partial_slabs = nr_slabs;
 }
+
+static inline unsigned int slub_get_cpu_partial(struct kmem_cache *s)
+{
+       return s->cpu_partial_slabs;
+}
 #else
 static inline void
 slub_set_cpu_partial(struct kmem_cache *s, unsigned int nr_objects)
 {
 }
+
+static inline unsigned int slub_get_cpu_partial(struct kmem_cache *s)
+{
+       return 0;
+}
 #endif /* CONFIG_SLUB_CPU_PARTIAL */
 
 /*
@@ -845,26 +875,6 @@ static void print_section(char *level, char *text, u8 *addr,
        metadata_access_disable();
 }
 
-/*
- * See comment in calculate_sizes().
- */
-static inline bool freeptr_outside_object(struct kmem_cache *s)
-{
-       return s->offset >= s->inuse;
-}
-
-/*
- * Return offset of the end of info block which is inuse + free pointer if
- * not overlapping with object.
- */
-static inline unsigned int get_info_end(struct kmem_cache *s)
-{
-       if (freeptr_outside_object(s))
-               return s->inuse + sizeof(void *);
-       else
-               return s->inuse;
-}
-
 static struct track *get_track(struct kmem_cache *s, void *object,
        enum track_item alloc)
 {
@@ -2092,15 +2102,20 @@ bool slab_free_hook(struct kmem_cache *s, void *x, bool init)
         *
         * The initialization memset's clear the object and the metadata,
         * but don't touch the SLAB redzone.
+        *
+        * The object's freepointer is also avoided if stored outside the
+        * object.
         */
        if (unlikely(init)) {
                int rsize;
+               unsigned int inuse;
 
+               inuse = get_info_end(s);
                if (!kasan_has_integrated_init())
                        memset(kasan_reset_tag(x), 0, s->object_size);
                rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad : 0;
-               memset((char *)kasan_reset_tag(x) + s->inuse, 0,
-                      s->size - s->inuse - rsize);
+               memset((char *)kasan_reset_tag(x) + inuse, 0,
+                      s->size - inuse - rsize);
        }
        /* KASAN might put x into memory quarantine, delaying its reuse. */
        return !kasan_slab_free(s, x, init);
@@ -2604,19 +2619,18 @@ static struct slab *get_partial_node(struct kmem_cache *s,
                if (!partial) {
                        partial = slab;
                        stat(s, ALLOC_FROM_PARTIAL);
+
+                       if ((slub_get_cpu_partial(s) == 0)) {
+                               break;
+                       }
                } else {
                        put_cpu_partial(s, slab, 0);
                        stat(s, CPU_PARTIAL_NODE);
-                       partial_slabs++;
-               }
-#ifdef CONFIG_SLUB_CPU_PARTIAL
-               if (!kmem_cache_has_cpu_partial(s)
-                       || partial_slabs > s->cpu_partial_slabs / 2)
-                       break;
-#else
-               break;
-#endif
 
+                       if (++partial_slabs > slub_get_cpu_partial(s) / 2) {
+                               break;
+                       }
+               }
        }
        spin_unlock_irqrestore(&n->list_lock, flags);
        return partial;
@@ -2699,7 +2713,7 @@ static struct slab *get_partial(struct kmem_cache *s, int node,
                searchnode = numa_mem_id();
 
        slab = get_partial_node(s, get_node(s, searchnode), pc);
-       if (slab || node != NUMA_NO_NODE)
+       if (slab || (node != NUMA_NO_NODE && (pc->flags & __GFP_THISNODE)))
                return slab;
 
        return get_any_partial(s, pc);
@@ -2797,7 +2811,7 @@ static void deactivate_slab(struct kmem_cache *s, struct slab *slab,
        struct slab new;
        struct slab old;
 
-       if (slab->freelist) {
+       if (READ_ONCE(slab->freelist)) {
                stat(s, DEACTIVATE_REMOTE_FREES);
                tail = DEACTIVATE_TO_TAIL;
        }
@@ -3229,6 +3243,43 @@ static unsigned long count_partial(struct kmem_cache_node *n,
 #endif /* CONFIG_SLUB_DEBUG || SLAB_SUPPORTS_SYSFS */
 
 #ifdef CONFIG_SLUB_DEBUG
+#define MAX_PARTIAL_TO_SCAN 10000
+
+static unsigned long count_partial_free_approx(struct kmem_cache_node *n)
+{
+       unsigned long flags;
+       unsigned long x = 0;
+       struct slab *slab;
+
+       spin_lock_irqsave(&n->list_lock, flags);
+       if (n->nr_partial <= MAX_PARTIAL_TO_SCAN) {
+               list_for_each_entry(slab, &n->partial, slab_list)
+                       x += slab->objects - slab->inuse;
+       } else {
+               /*
+                * For a long list, approximate the total count of objects in
+                * it to meet the limit on the number of slabs to scan.
+                * Scan from both the list's head and tail for better accuracy.
+                */
+               unsigned long scanned = 0;
+
+               list_for_each_entry(slab, &n->partial, slab_list) {
+                       x += slab->objects - slab->inuse;
+                       if (++scanned == MAX_PARTIAL_TO_SCAN / 2)
+                               break;
+               }
+               list_for_each_entry_reverse(slab, &n->partial, slab_list) {
+                       x += slab->objects - slab->inuse;
+                       if (++scanned == MAX_PARTIAL_TO_SCAN)
+                               break;
+               }
+               x = mult_frac(x, n->nr_partial, scanned);
+               x = min(x, node_nr_objs(n));
+       }
+       spin_unlock_irqrestore(&n->list_lock, flags);
+       return x;
+}
+
 static noinline void
 slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
 {
@@ -3255,7 +3306,7 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
                unsigned long nr_objs;
                unsigned long nr_free;
 
-               nr_free  = count_partial(n, count_free);
+               nr_free  = count_partial_free_approx(n);
                nr_slabs = node_nr_slabs(n);
                nr_objs  = node_nr_objs(n);
 
@@ -3375,6 +3426,7 @@ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
        struct slab *slab;
        unsigned long flags;
        struct partial_context pc;
+       bool try_thisnode = true;
 
        stat(s, ALLOC_SLOWPATH);
 
@@ -3501,6 +3553,21 @@ new_slab:
 new_objects:
 
        pc.flags = gfpflags;
+       /*
+        * When a preferred node is indicated but no __GFP_THISNODE
+        *
+        * 1) try to get a partial slab from target node only by having
+        *    __GFP_THISNODE in pc.flags for get_partial()
+        * 2) if 1) failed, try to allocate a new slab from target node with
+        *    GPF_NOWAIT | __GFP_THISNODE opportunistically
+        * 3) if 2) failed, retry with original gfpflags which will allow
+        *    get_partial() try partial lists of other nodes before potentially
+        *    allocating new page from other nodes
+        */
+       if (unlikely(node != NUMA_NO_NODE && !(gfpflags & __GFP_THISNODE)
+                    && try_thisnode))
+               pc.flags = GFP_NOWAIT | __GFP_THISNODE;
+
        pc.orig_size = orig_size;
        slab = get_partial(s, node, &pc);
        if (slab) {
@@ -3522,10 +3589,15 @@ new_objects:
        }
 
        slub_put_cpu_ptr(s->cpu_slab);
-       slab = new_slab(s, gfpflags, node);
+       slab = new_slab(s, pc.flags, node);
        c = slub_get_cpu_ptr(s->cpu_slab);
 
        if (unlikely(!slab)) {
+               if (node != NUMA_NO_NODE && !(gfpflags & __GFP_THISNODE)
+                   && try_thisnode) {
+                       try_thisnode = false;
+                       goto new_objects;
+               }
                slab_out_of_memory(s, gfpflags, node);
                return NULL;
        }
@@ -3722,7 +3794,8 @@ static void *__slab_alloc_node(struct kmem_cache *s,
 static __always_inline void maybe_wipe_obj_freeptr(struct kmem_cache *s,
                                                   void *obj)
 {
-       if (unlikely(slab_want_init_on_free(s)) && obj)
+       if (unlikely(slab_want_init_on_free(s)) && obj &&
+           !freeptr_outside_object(s))
                memset((void *)((char *)kasan_reset_tag(obj) + s->offset),
                        0, sizeof(void *));
 }
@@ -4226,7 +4299,7 @@ redo:
        c = raw_cpu_ptr(s->cpu_slab);
        tid = READ_ONCE(c->tid);
 
-       /* Same with comment on barrier() in slab_alloc_node() */
+       /* Same with comment on barrier() in __slab_alloc_node() */
        barrier();
 
        if (unlikely(slab != c->slab)) {
@@ -4847,7 +4920,6 @@ static void early_kmem_cache_node_alloc(int node)
        BUG_ON(!n);
 #ifdef CONFIG_SLUB_DEBUG
        init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
-       init_tracking(kmem_cache_node, n);
 #endif
        n = kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false);
        slab->freelist = get_freepointer(kmem_cache_node, n);
@@ -5060,9 +5132,7 @@ static int calculate_sizes(struct kmem_cache *s)
        if ((int)order < 0)
                return 0;
 
-       s->allocflags = 0;
-       if (order)
-               s->allocflags |= __GFP_COMP;
+       s->allocflags = __GFP_COMP;
 
        if (s->flags & SLAB_CACHE_DMA)
                s->allocflags |= GFP_DMA;
@@ -6036,7 +6106,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s,
                                else if (flags & SO_OBJECTS)
                                        WARN_ON_ONCE(1);
                                else
-                                       x = slab->slabs;
+                                       x = data_race(slab->slabs);
                                total += x;
                                nodes[node] += x;
                        }
@@ -6241,7 +6311,7 @@ static ssize_t slabs_cpu_partial_show(struct kmem_cache *s, char *buf)
                slab = slub_percpu_partial(per_cpu_ptr(s->cpu_slab, cpu));
 
                if (slab)
-                       slabs += slab->slabs;
+                       slabs += data_race(slab->slabs);
        }
 #endif
 
@@ -6255,7 +6325,7 @@ static ssize_t slabs_cpu_partial_show(struct kmem_cache *s, char *buf)
 
                slab = slub_percpu_partial(per_cpu_ptr(s->cpu_slab, cpu));
                if (slab) {
-                       slabs = READ_ONCE(slab->slabs);
+                       slabs = data_race(slab->slabs);
                        objects = (slabs * oo_objects(s->oo)) / 2;
                        len += sysfs_emit_at(buf, len, " C%d=%d(%d)",
                                             cpu, objects, slabs);
@@ -7089,7 +7159,7 @@ void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo)
        for_each_kmem_cache_node(s, node, n) {
                nr_slabs += node_nr_slabs(n);
                nr_objs += node_nr_objs(n);
-               nr_free += count_partial(n, count_free);
+               nr_free += count_partial_free_approx(n);
        }
 
        sinfo->active_objs = nr_objs - nr_free;
@@ -7099,14 +7169,4 @@ void get_slabinfo(struct kmem_cache *s, struct slabinfo *sinfo)
        sinfo->objects_per_slab = oo_objects(s->oo);
        sinfo->cache_order = oo_order(s->oo);
 }
-
-void slabinfo_show_stats(struct seq_file *m, struct kmem_cache *s)
-{
-}
-
-ssize_t slabinfo_write(struct file *file, const char __user *buffer,
-                      size_t count, loff_t *ppos)
-{
-       return -EIO;
-}
 #endif /* CONFIG_SLUB_DEBUG */
index 3c3539c573e7fec47b2ac883e18d7644d40197c3..829f7b1089fc6f64b86ea05852ec0fa229d3fa7e 100644 (file)
@@ -316,6 +316,38 @@ out_release:
        goto out;
 }
 
+static int mfill_atomic_pte_zeroed_folio(pmd_t *dst_pmd,
+                                        struct vm_area_struct *dst_vma,
+                                        unsigned long dst_addr)
+{
+       struct folio *folio;
+       int ret = -ENOMEM;
+
+       folio = vma_alloc_zeroed_movable_folio(dst_vma, dst_addr);
+       if (!folio)
+               return ret;
+
+       if (mem_cgroup_charge(folio, dst_vma->vm_mm, GFP_KERNEL))
+               goto out_put;
+
+       /*
+        * The memory barrier inside __folio_mark_uptodate makes sure that
+        * zeroing out the folio become visible before mapping the page
+        * using set_pte_at(). See do_anonymous_page().
+        */
+       __folio_mark_uptodate(folio);
+
+       ret = mfill_atomic_install_pte(dst_pmd, dst_vma, dst_addr,
+                                      &folio->page, true, 0);
+       if (ret)
+               goto out_put;
+
+       return 0;
+out_put:
+       folio_put(folio);
+       return ret;
+}
+
 static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd,
                                     struct vm_area_struct *dst_vma,
                                     unsigned long dst_addr)
@@ -324,6 +356,9 @@ static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd,
        spinlock_t *ptl;
        int ret;
 
+       if (mm_forbids_zeropage(dst_vma->vm_mm))
+               return mfill_atomic_pte_zeroed_folio(dst_pmd, dst_vma, dst_addr);
+
        _dst_pte = pte_mkspecial(pfn_pte(my_zero_pfn(dst_addr),
                                         dst_vma->vm_page_prot));
        ret = -EAGAIN;
index 68fa001648cc1cb766d8fa4111e88c3fbbf257e8..125427cbdb87bcc4bb30a076bcba91119490709c 100644 (file)
@@ -2710,7 +2710,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
                 * get_order(0) returns funny result. Just warn and terminate
                 * early.
                 */
-               return NULL;
+               return ERR_PTR(-EINVAL);
        }
        order = get_order(size);
 
index f001582345052f8c26e008058ae5f721f8bc224d..9404dd551dfd2850117d4edf9b7fd25e3ba84322 100644 (file)
@@ -478,6 +478,8 @@ static struct sk_buff *vlan_gro_receive(struct list_head *head,
        if (unlikely(!vhdr))
                goto out;
 
+       NAPI_GRO_CB(skb)->network_offsets[NAPI_GRO_CB(skb)->encap_mark] = hlen;
+
        type = vhdr->h_vlan_encapsulated_proto;
 
        ptype = gro_find_receive_by_type(type);
index 00ebce9e5a6570eebf0be94ea3f219c4242a00a5..bcdab9c23b402d59cc9f0ba9590de2ceea075286 100644 (file)
@@ -5,6 +5,7 @@
 
 menuconfig NET_9P
        tristate "Plan 9 Resource Sharing Support (9P2000)"
+       select NETFS_SUPPORT
        help
          If you say Y here, you will get experimental support for
          Plan 9 resource sharing via the 9P2000 protocol.
index f7e90b4769bba92ef8187b0a96cb310f0c13d5f8..00774656eeac8368f538e59cb8b456af405a3469 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sched/signal.h>
 #include <linux/uaccess.h>
 #include <linux/uio.h>
+#include <linux/netfs.h>
 #include <net/9p/9p.h>
 #include <linux/parser.h>
 #include <linux/seq_file.h>
@@ -1661,6 +1662,54 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err)
 }
 EXPORT_SYMBOL(p9_client_write);
 
+void
+p9_client_write_subreq(struct netfs_io_subrequest *subreq)
+{
+       struct netfs_io_request *wreq = subreq->rreq;
+       struct p9_fid *fid = wreq->netfs_priv;
+       struct p9_client *clnt = fid->clnt;
+       struct p9_req_t *req;
+       unsigned long long start = subreq->start + subreq->transferred;
+       int written, len = subreq->len - subreq->transferred;
+       int err;
+
+       p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu len %d\n",
+                fid->fid, start, len);
+
+       /* Don't bother zerocopy for small IO (< 1024) */
+       if (clnt->trans_mod->zc_request && len > 1024) {
+               req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, &subreq->io_iter,
+                                      0, wreq->len, P9_ZC_HDR_SZ, "dqd",
+                                      fid->fid, start, len);
+       } else {
+               req = p9_client_rpc(clnt, P9_TWRITE, "dqV", fid->fid,
+                                   start, len, &subreq->io_iter);
+       }
+       if (IS_ERR(req)) {
+               netfs_write_subrequest_terminated(subreq, PTR_ERR(req), false);
+               return;
+       }
+
+       err = p9pdu_readf(&req->rc, clnt->proto_version, "d", &written);
+       if (err) {
+               trace_9p_protocol_dump(clnt, &req->rc);
+               p9_req_put(clnt, req);
+               netfs_write_subrequest_terminated(subreq, err, false);
+               return;
+       }
+
+       if (written > len) {
+               pr_err("bogus RWRITE count (%d > %u)\n", written, len);
+               written = len;
+       }
+
+       p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", len);
+
+       p9_req_put(clnt, req);
+       netfs_write_subrequest_terminated(subreq, written, false);
+}
+EXPORT_SYMBOL(p9_client_write_subreq);
+
 struct p9_wstat *p9_client_stat(struct p9_fid *fid)
 {
        int err;
index 198f5ba2feae6662cd7363b72db6d412f03b48c7..b068651984fe3dec6c23337ae095a6f13a14ffa3 100644 (file)
@@ -88,6 +88,7 @@ static inline void atalk_remove_socket(struct sock *sk)
 static struct sock *atalk_search_socket(struct sockaddr_at *to,
                                        struct atalk_iface *atif)
 {
+       struct sock *def_socket = NULL;
        struct sock *s;
 
        read_lock_bh(&atalk_sockets_lock);
@@ -98,8 +99,20 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
                        continue;
 
                if (to->sat_addr.s_net == ATADDR_ANYNET &&
-                   to->sat_addr.s_node == ATADDR_BCAST)
-                       goto found;
+                   to->sat_addr.s_node == ATADDR_BCAST) {
+                       if (atif->address.s_node == at->src_node &&
+                           atif->address.s_net == at->src_net) {
+                               /* This socket's address matches the address of the interface
+                                * that received the packet -- use it
+                                */
+                               goto found;
+                       }
+
+                       /* Continue searching for a socket matching the interface address,
+                        * but use this socket by default if no other one is found
+                        */
+                       def_socket = s;
+               }
 
                if (to->sat_addr.s_net == at->src_net &&
                    (to->sat_addr.s_node == at->src_node ||
@@ -116,7 +129,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
                        goto found;
                }
        }
-       s = NULL;
+       s = def_socket;
 found:
        read_unlock_bh(&atalk_sockets_lock);
        return s;
index a7028d38c1f5cc756aed90c3859638284996011f..bc5086423ab839d6ad451234dc3bece65a3096fa 100644 (file)
@@ -2768,8 +2768,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
 
        hci_unregister_suspend_notifier(hdev);
 
-       msft_unregister(hdev);
-
        hci_dev_do_close(hdev);
 
        if (!test_bit(HCI_INIT, &hdev->flags) &&
@@ -2823,6 +2821,7 @@ void hci_release_dev(struct hci_dev *hdev)
        hci_discovery_filter_clear(hdev);
        hci_blocked_keys_clear(hdev);
        hci_codec_list_clear(&hdev->local_codecs);
+       msft_release(hdev);
        hci_dev_unlock(hdev);
 
        ida_destroy(&hdev->unset_handle_ida);
index 4a27e4a17a67449ffd8a37cb057357e20881667c..d72d238c1656ed442aa89c3026dbafb9ac1cdf6b 100644 (file)
@@ -7037,6 +7037,8 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
                        u16 handle = le16_to_cpu(ev->bis[i]);
 
                        bis = hci_conn_hash_lookup_handle(hdev, handle);
+                       if (!bis)
+                               continue;
 
                        set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
                        hci_connect_cfm(bis, ev->status);
index 84fc70862d78aeef25d6ca9e6df7fb468338852e..9223b1a698e3a82a6d9ba5a7e864e78c64a2225b 100644 (file)
@@ -415,6 +415,9 @@ static void l2cap_chan_timeout(struct work_struct *work)
 
        BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
 
+       if (!conn)
+               return;
+
        mutex_lock(&conn->chan_lock);
        /* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
         * this work. No need to call l2cap_chan_hold(chan) here again.
@@ -3902,13 +3905,12 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
        return 0;
 }
 
-static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
-                                       struct l2cap_cmd_hdr *cmd,
-                                       u8 *data, u8 rsp_code, u8 amp_id)
+static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
+                         u8 *data, u8 rsp_code, u8 amp_id)
 {
        struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
        struct l2cap_conn_rsp rsp;
-       struct l2cap_chan *chan = NULL, *pchan;
+       struct l2cap_chan *chan = NULL, *pchan = NULL;
        int result, status = L2CAP_CS_NO_INFO;
 
        u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3921,7 +3923,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
                                         &conn->hcon->dst, ACL_LINK);
        if (!pchan) {
                result = L2CAP_CR_BAD_PSM;
-               goto sendresp;
+               goto response;
        }
 
        mutex_lock(&conn->chan_lock);
@@ -4008,17 +4010,15 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
        }
 
 response:
-       l2cap_chan_unlock(pchan);
-       mutex_unlock(&conn->chan_lock);
-       l2cap_chan_put(pchan);
-
-sendresp:
        rsp.scid   = cpu_to_le16(scid);
        rsp.dcid   = cpu_to_le16(dcid);
        rsp.result = cpu_to_le16(result);
        rsp.status = cpu_to_le16(status);
        l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
 
+       if (!pchan)
+               return;
+
        if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
                struct l2cap_info_req info;
                info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
@@ -4041,7 +4041,9 @@ sendresp:
                chan->num_conf_req++;
        }
 
-       return chan;
+       l2cap_chan_unlock(pchan);
+       mutex_unlock(&conn->chan_lock);
+       l2cap_chan_put(pchan);
 }
 
 static int l2cap_connect_req(struct l2cap_conn *conn,
index 9612c5d1b13f6d2eed675d94d81c5e9b1483afa3..d039683d3bdd4128a0c911a12259cfb1f1abbbaf 100644 (file)
@@ -769,7 +769,7 @@ void msft_register(struct hci_dev *hdev)
        mutex_init(&msft->filter_lock);
 }
 
-void msft_unregister(struct hci_dev *hdev)
+void msft_release(struct hci_dev *hdev)
 {
        struct msft_data *msft = hdev->msft_data;
 
index 2a63205b377b70a79044b983d49f140fd3eb5578..fe538e9c91c0194db03c0dd32e664a4cd20d5d98 100644 (file)
@@ -14,7 +14,7 @@
 
 bool msft_monitor_supported(struct hci_dev *hdev);
 void msft_register(struct hci_dev *hdev);
-void msft_unregister(struct hci_dev *hdev);
+void msft_release(struct hci_dev *hdev);
 void msft_do_open(struct hci_dev *hdev);
 void msft_do_close(struct hci_dev *hdev);
 void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb);
@@ -35,7 +35,7 @@ static inline bool msft_monitor_supported(struct hci_dev *hdev)
 }
 
 static inline void msft_register(struct hci_dev *hdev) {}
-static inline void msft_unregister(struct hci_dev *hdev) {}
+static inline void msft_release(struct hci_dev *hdev) {}
 static inline void msft_do_open(struct hci_dev *hdev) {}
 static inline void msft_do_close(struct hci_dev *hdev) {}
 static inline void msft_vendor_evt(struct hci_dev *hdev, void *data,
index 5d03c5440b06f843e654ddb0e3d3f83d4dd0cfd9..e0ad30862ee4142cac48d0538fcec9df6e97b8b2 100644 (file)
@@ -83,6 +83,10 @@ static void sco_sock_timeout(struct work_struct *work)
        struct sock *sk;
 
        sco_conn_lock(conn);
+       if (!conn->hcon) {
+               sco_conn_unlock(conn);
+               return;
+       }
        sk = conn->sk;
        if (sk)
                sock_hold(sk);
index 7431f89e897b9549a0c35d9431e36b6de2e80022..d97064d460dc773f2d51413f80e58476d8c01f1a 100644 (file)
@@ -258,6 +258,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
 {
        struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
        const unsigned char *src = eth_hdr(skb)->h_source;
+       struct sk_buff *nskb;
 
        if (!should_deliver(p, skb))
                return;
@@ -266,12 +267,16 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
        if (skb->dev == p->dev && ether_addr_equal(src, addr))
                return;
 
-       skb = skb_copy(skb, GFP_ATOMIC);
-       if (!skb) {
+       __skb_push(skb, ETH_HLEN);
+       nskb = pskb_copy(skb, GFP_ATOMIC);
+       __skb_pull(skb, ETH_HLEN);
+       if (!nskb) {
                DEV_STATS_INC(dev, tx_dropped);
                return;
        }
 
+       skb = nskb;
+       __skb_pull(skb, ETH_HLEN);
        if (!is_broadcast_ether_addr(addr))
                memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
 
index 8adf95765cdd967a15b2661dfb454db0ccf350b0..ae5254f712c94b0c656fda5fe065ee635252a67e 100644 (file)
@@ -4360,10 +4360,12 @@ static __always_inline int __xdp_do_redirect_frame(struct bpf_redirect_info *ri,
        enum bpf_map_type map_type = ri->map_type;
        void *fwd = ri->tgt_value;
        u32 map_id = ri->map_id;
+       u32 flags = ri->flags;
        struct bpf_map *map;
        int err;
 
        ri->map_id = 0; /* Valid map id idr range: [1,INT_MAX[ */
+       ri->flags = 0;
        ri->map_type = BPF_MAP_TYPE_UNSPEC;
 
        if (unlikely(!xdpf)) {
@@ -4375,11 +4377,20 @@ static __always_inline int __xdp_do_redirect_frame(struct bpf_redirect_info *ri,
        case BPF_MAP_TYPE_DEVMAP:
                fallthrough;
        case BPF_MAP_TYPE_DEVMAP_HASH:
-               map = READ_ONCE(ri->map);
-               if (unlikely(map)) {
+               if (unlikely(flags & BPF_F_BROADCAST)) {
+                       map = READ_ONCE(ri->map);
+
+                       /* The map pointer is cleared when the map is being torn
+                        * down by bpf_clear_redirect_map()
+                        */
+                       if (unlikely(!map)) {
+                               err = -ENOENT;
+                               break;
+                       }
+
                        WRITE_ONCE(ri->map, NULL);
                        err = dev_map_enqueue_multi(xdpf, dev, map,
-                                                   ri->flags & BPF_F_EXCLUDE_INGRESS);
+                                                   flags & BPF_F_EXCLUDE_INGRESS);
                } else {
                        err = dev_map_enqueue(fwd, xdpf, dev);
                }
@@ -4442,9 +4453,9 @@ EXPORT_SYMBOL_GPL(xdp_do_redirect_frame);
 static int xdp_do_generic_redirect_map(struct net_device *dev,
                                       struct sk_buff *skb,
                                       struct xdp_buff *xdp,
-                                      struct bpf_prog *xdp_prog,
-                                      void *fwd,
-                                      enum bpf_map_type map_type, u32 map_id)
+                                      struct bpf_prog *xdp_prog, void *fwd,
+                                      enum bpf_map_type map_type, u32 map_id,
+                                      u32 flags)
 {
        struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
        struct bpf_map *map;
@@ -4454,11 +4465,20 @@ static int xdp_do_generic_redirect_map(struct net_device *dev,
        case BPF_MAP_TYPE_DEVMAP:
                fallthrough;
        case BPF_MAP_TYPE_DEVMAP_HASH:
-               map = READ_ONCE(ri->map);
-               if (unlikely(map)) {
+               if (unlikely(flags & BPF_F_BROADCAST)) {
+                       map = READ_ONCE(ri->map);
+
+                       /* The map pointer is cleared when the map is being torn
+                        * down by bpf_clear_redirect_map()
+                        */
+                       if (unlikely(!map)) {
+                               err = -ENOENT;
+                               break;
+                       }
+
                        WRITE_ONCE(ri->map, NULL);
                        err = dev_map_redirect_multi(dev, skb, xdp_prog, map,
-                                                    ri->flags & BPF_F_EXCLUDE_INGRESS);
+                                                    flags & BPF_F_EXCLUDE_INGRESS);
                } else {
                        err = dev_map_generic_redirect(fwd, skb, xdp_prog);
                }
@@ -4495,9 +4515,11 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
        enum bpf_map_type map_type = ri->map_type;
        void *fwd = ri->tgt_value;
        u32 map_id = ri->map_id;
+       u32 flags = ri->flags;
        int err;
 
        ri->map_id = 0; /* Valid map id idr range: [1,INT_MAX[ */
+       ri->flags = 0;
        ri->map_type = BPF_MAP_TYPE_UNSPEC;
 
        if (map_type == BPF_MAP_TYPE_UNSPEC && map_id == INT_MAX) {
@@ -4517,7 +4539,7 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
                return 0;
        }
 
-       return xdp_do_generic_redirect_map(dev, skb, xdp, xdp_prog, fwd, map_type, map_id);
+       return xdp_do_generic_redirect_map(dev, skb, xdp, xdp_prog, fwd, map_type, map_id, flags);
 err:
        _trace_xdp_redirect_err(dev, xdp_prog, ri->tgt_index, err);
        return err;
index 83f35d99a682c21dae11683fec72074a898fbac2..c7901253a1a8fc1e9425add77014e15b363a1623 100644 (file)
@@ -371,6 +371,7 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb, u32 nhoff)
        const skb_frag_t *frag0;
        unsigned int headlen;
 
+       NAPI_GRO_CB(skb)->network_offset = 0;
        NAPI_GRO_CB(skb)->data_offset = 0;
        headlen = skb_headlen(skb);
        NAPI_GRO_CB(skb)->frag0 = skb->data;
index f0540c5575157135b1dc5dece2220f81a408fb7e..9d690d32da33a1d9fa5b26234ce063f395093fe3 100644 (file)
@@ -69,12 +69,15 @@ DEFINE_COOKIE(net_cookie);
 
 static struct net_generic *net_alloc_generic(void)
 {
+       unsigned int gen_ptrs = READ_ONCE(max_gen_ptrs);
+       unsigned int generic_size;
        struct net_generic *ng;
-       unsigned int generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]);
+
+       generic_size = offsetof(struct net_generic, ptr[gen_ptrs]);
 
        ng = kzalloc(generic_size, GFP_KERNEL);
        if (ng)
-               ng->s.len = max_gen_ptrs;
+               ng->s.len = gen_ptrs;
 
        return ng;
 }
@@ -1307,7 +1310,11 @@ static int register_pernet_operations(struct list_head *list,
                if (error < 0)
                        return error;
                *ops->id = error;
-               max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1);
+               /* This does not require READ_ONCE as writers already hold
+                * pernet_ops_rwsem. But WRITE_ONCE is needed to protect
+                * net_alloc_generic.
+                */
+               WRITE_ONCE(max_gen_ptrs, max(max_gen_ptrs, *ops->id + 1));
        }
        error = __register_pernet_operations(list, ops);
        if (error) {
index a3d7847ce69d36401051526acf30211d96e2b24e..8ba6a4e4be26667e3fc2dbd46214f6954f6b65e0 100644 (file)
@@ -2530,7 +2530,7 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
 
                nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) {
                        if (nla_type(attr) != IFLA_VF_VLAN_INFO ||
-                           nla_len(attr) < NLA_HDRLEN) {
+                           nla_len(attr) < sizeof(struct ifla_vf_vlan_info)) {
                                return -EINVAL;
                        }
                        if (len >= MAX_VLAN_LIST_LEN)
index b99127712e6704dda41636014db46096da171bfd..4096e679f61c76041223b894e3ee4f9a8a051000 100644 (file)
@@ -2123,11 +2123,17 @@ static inline int skb_alloc_rx_flag(const struct sk_buff *skb)
 
 struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
 {
-       int headerlen = skb_headroom(skb);
-       unsigned int size = skb_end_offset(skb) + skb->data_len;
-       struct sk_buff *n = __alloc_skb(size, gfp_mask,
-                                       skb_alloc_rx_flag(skb), NUMA_NO_NODE);
+       struct sk_buff *n;
+       unsigned int size;
+       int headerlen;
+
+       if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
+               return NULL;
 
+       headerlen = skb_headroom(skb);
+       size = skb_end_offset(skb) + skb->data_len;
+       n = __alloc_skb(size, gfp_mask,
+                       skb_alloc_rx_flag(skb), NUMA_NO_NODE);
        if (!n)
                return NULL;
 
@@ -2455,12 +2461,17 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
        /*
         *      Allocate the copy buffer
         */
-       struct sk_buff *n = __alloc_skb(newheadroom + skb->len + newtailroom,
-                                       gfp_mask, skb_alloc_rx_flag(skb),
-                                       NUMA_NO_NODE);
-       int oldheadroom = skb_headroom(skb);
        int head_copy_len, head_copy_off;
+       struct sk_buff *n;
+       int oldheadroom;
+
+       if (WARN_ON_ONCE(skb_shinfo(skb)->gso_type & SKB_GSO_FRAGLIST))
+               return NULL;
 
+       oldheadroom = skb_headroom(skb);
+       n = __alloc_skb(newheadroom + skb->len + newtailroom,
+                       gfp_mask, skb_alloc_rx_flag(skb),
+                       NUMA_NO_NODE);
        if (!n)
                return NULL;
 
index 4d75ef9d24bfa7cbffe642448f5116ac0b943ed2..fd20aae30be23cc2241f081a1d56215f9693cab0 100644 (file)
@@ -1226,11 +1226,8 @@ static void sk_psock_verdict_data_ready(struct sock *sk)
 
                rcu_read_lock();
                psock = sk_psock(sk);
-               if (psock) {
-                       read_lock_bh(&sk->sk_callback_lock);
+               if (psock)
                        sk_psock_data_ready(sk, psock);
-                       read_unlock_bh(&sk->sk_callback_lock);
-               }
                rcu_read_unlock();
        }
 }
index e9d45133d6412e57d88414b0baffaec625d0d724..5afc450d0855337f1883dd34f71f6c9fa3bfdb78 100644 (file)
@@ -61,39 +61,36 @@ static bool hsr_check_carrier(struct hsr_port *master)
        return false;
 }
 
-static void hsr_check_announce(struct net_device *hsr_dev,
-                              unsigned char old_operstate)
+static void hsr_check_announce(struct net_device *hsr_dev)
 {
        struct hsr_priv *hsr;
 
        hsr = netdev_priv(hsr_dev);
-
-       if (READ_ONCE(hsr_dev->operstate) == IF_OPER_UP && old_operstate != IF_OPER_UP) {
-               /* Went up */
-               hsr->announce_count = 0;
-               mod_timer(&hsr->announce_timer,
-                         jiffies + msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL));
+       if (netif_running(hsr_dev) && netif_oper_up(hsr_dev)) {
+               /* Enable announce timer and start sending supervisory frames */
+               if (!timer_pending(&hsr->announce_timer)) {
+                       hsr->announce_count = 0;
+                       mod_timer(&hsr->announce_timer, jiffies +
+                                 msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL));
+               }
+       } else {
+               /* Deactivate the announce timer  */
+               timer_delete(&hsr->announce_timer);
        }
-
-       if (READ_ONCE(hsr_dev->operstate) != IF_OPER_UP && old_operstate == IF_OPER_UP)
-               /* Went down */
-               del_timer(&hsr->announce_timer);
 }
 
 void hsr_check_carrier_and_operstate(struct hsr_priv *hsr)
 {
        struct hsr_port *master;
-       unsigned char old_operstate;
        bool has_carrier;
 
        master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
        /* netif_stacked_transfer_operstate() cannot be used here since
         * it doesn't set IF_OPER_LOWERLAYERDOWN (?)
         */
-       old_operstate = READ_ONCE(master->dev->operstate);
        has_carrier = hsr_check_carrier(master);
        hsr_set_operstate(master, has_carrier);
-       hsr_check_announce(master->dev, old_operstate);
+       hsr_check_announce(master->dev);
 }
 
 int hsr_get_max_mtu(struct hsr_priv *hsr)
index 55bd72997b31063b7baad350fdcff40e938aecb8..fafb123f798be346c247dac0f9dc8e498e034349 100644 (file)
@@ -1572,6 +1572,7 @@ struct sk_buff *inet_gro_receive(struct list_head *head, struct sk_buff *skb)
        /* The above will be needed by the transport layer if there is one
         * immediately following this IP hdr.
         */
+       NAPI_GRO_CB(skb)->inner_network_offset = off;
 
        /* Note : No need to call skb_gro_postpull_rcsum() here,
         * as we already checked checksum over ipv4 header was 0
index 1fe794967211e249016df00dc3c2ae230d71dcff..39229fd0601a11c3f2e58cd1e75db165a443b1a2 100644 (file)
@@ -1473,7 +1473,7 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
                 * by icmp_hdr(skb)->type.
                 */
                if (sk->sk_type == SOCK_RAW &&
-                   !inet_test_bit(HDRINCL, sk))
+                   !(fl4->flowi4_flags & FLOWI_FLAG_KNOWN_NH))
                        icmp_type = fl4->fl4_icmp_type;
                else
                        icmp_type = icmp_hdr(skb)->type;
index dcb11f22cbf2b437405d1b373dd0ebc37d02c9ec..4cb43401e0e06c5003c268c28bf0882ac4e8b4e0 100644 (file)
@@ -612,6 +612,9 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                            (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
                           daddr, saddr, 0, 0, sk->sk_uid);
 
+       fl4.fl4_icmp_type = 0;
+       fl4.fl4_icmp_code = 0;
+
        if (!hdrincl) {
                rfv.msg = msg;
                rfv.hlen = 0;
index e767721b3a588b5d56567ae7badf5dffcd35a76a..66d77faca64f6db95e04f4c0e7dd3892628ae3f7 100644 (file)
@@ -2710,7 +2710,7 @@ void tcp_shutdown(struct sock *sk, int how)
        /* If we've already sent a FIN, or it's a closed state, skip this. */
        if ((1 << sk->sk_state) &
            (TCPF_ESTABLISHED | TCPF_SYN_SENT |
-            TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) {
+            TCPF_CLOSE_WAIT)) {
                /* Clear out any half completed packets.  FIN if needed. */
                if (tcp_close_state(sk))
                        tcp_send_fin(sk);
@@ -2819,7 +2819,7 @@ void __tcp_close(struct sock *sk, long timeout)
                 * machine. State transitions:
                 *
                 * TCP_ESTABLISHED -> TCP_FIN_WAIT1
-                * TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible)
+                * TCP_SYN_RECV -> TCP_FIN_WAIT1 (it is difficult)
                 * TCP_CLOSE_WAIT -> TCP_LAST_ACK
                 *
                 * are legal only when FIN has been sent (i.e. in window),
index 5d874817a78db31a4a807ab80e9158300329423d..a140d9f7a0a36e6a0b90c97a44a1e54e7639c71f 100644 (file)
@@ -6761,6 +6761,8 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
 
                tcp_initialize_rcv_mss(sk);
                tcp_fast_path_on(tp);
+               if (sk->sk_shutdown & SEND_SHUTDOWN)
+                       tcp_shutdown(sk, SEND_SHUTDOWN);
                break;
 
        case TCP_FIN_WAIT1: {
index a22ee58387518ac5ea602d0f66be41dfa0f4c1ee..e0cef75f85fb92c173700b5b417b7e6c91e39716 100644 (file)
@@ -154,6 +154,12 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
        if (tcptw->tw_ts_recent_stamp &&
            (!twp || (reuse && time_after32(ktime_get_seconds(),
                                            tcptw->tw_ts_recent_stamp)))) {
+               /* inet_twsk_hashdance() sets sk_refcnt after putting twsk
+                * and releasing the bucket lock.
+                */
+               if (unlikely(!refcount_inc_not_zero(&sktw->sk_refcnt)))
+                       return 0;
+
                /* In case of repair and re-using TIME-WAIT sockets we still
                 * want to be sure that it is safe as above but honor the
                 * sequence numbers and time stamps set as part of the repair
@@ -174,7 +180,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
                        tp->rx_opt.ts_recent       = tcptw->tw_ts_recent;
                        tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
                }
-               sock_hold(sktw);
+
                return 1;
        }
 
index e3167ad965676facaacd8f82848c52cf966f97c3..02caeb7bcf6342713019d31891998fdbe426b573 100644 (file)
@@ -3563,7 +3563,9 @@ void tcp_send_fin(struct sock *sk)
                        return;
                }
        } else {
-               skb = alloc_skb_fclone(MAX_TCP_HEADER, sk->sk_allocation);
+               skb = alloc_skb_fclone(MAX_TCP_HEADER,
+                                      sk_gfp_mask(sk, GFP_ATOMIC |
+                                                      __GFP_NOWARN));
                if (unlikely(!skb))
                        return;
 
index 420905be5f30c944ff360b349ae29d66104e0286..b32cf2eeeb41d1fc0bbe24e4888301f344ec8488 100644 (file)
@@ -532,7 +532,8 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
 struct sock *udp4_lib_lookup_skb(const struct sk_buff *skb,
                                 __be16 sport, __be16 dport)
 {
-       const struct iphdr *iph = ip_hdr(skb);
+       const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
+       const struct iphdr *iph = (struct iphdr *)(skb->data + offset);
        struct net *net = dev_net(skb->dev);
        int iif, sdif;
 
index 3498dd1d0694dc3ddb984177d2ddffb7b8abd0b9..8721fe5beca2bea692eb2cfa454e724e649cea6d 100644 (file)
@@ -471,6 +471,7 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
        struct sk_buff *p;
        unsigned int ulen;
        int ret = 0;
+       int flush;
 
        /* requires non zero csum, for symmetry with GSO */
        if (!uh->check) {
@@ -504,13 +505,22 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head,
                        return p;
                }
 
+               flush = NAPI_GRO_CB(p)->flush;
+
+               if (NAPI_GRO_CB(p)->flush_id != 1 ||
+                   NAPI_GRO_CB(p)->count != 1 ||
+                   !NAPI_GRO_CB(p)->is_atomic)
+                       flush |= NAPI_GRO_CB(p)->flush_id;
+               else
+                       NAPI_GRO_CB(p)->is_atomic = false;
+
                /* Terminate the flow on len mismatch or if it grow "too much".
                 * Under small packet flood GRO count could elsewhere grow a lot
                 * leading to excessive truesize values.
                 * On len mismatch merge the first packet shorter than gso_size,
                 * otherwise complete the GRO packet.
                 */
-               if (ulen > ntohs(uh2->len)) {
+               if (ulen > ntohs(uh2->len) || flush) {
                        pp = p;
                } else {
                        if (NAPI_GRO_CB(skb)->is_flist) {
@@ -718,7 +728,8 @@ EXPORT_SYMBOL(udp_gro_complete);
 
 INDIRECT_CALLABLE_SCOPE int udp4_gro_complete(struct sk_buff *skb, int nhoff)
 {
-       const struct iphdr *iph = ip_hdr(skb);
+       const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
+       const struct iphdr *iph = (struct iphdr *)(skb->data + offset);
        struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
 
        /* do fraglist only if there is no outer UDP encap (or we already processed it) */
index dae35101d18959b73e60904f2225e59d1423455a..86382e08140ee038189d408edd973c60695f200c 100644 (file)
@@ -63,7 +63,11 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
        ip_send_check(iph);
 
        if (xo && (xo->flags & XFRM_GRO)) {
-               skb_mac_header_rebuild(skb);
+               /* The full l2 header needs to be preserved so that re-injecting the packet at l2
+                * works correctly in the presence of vlan tags.
+                */
+               skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
+               skb_reset_network_header(skb);
                skb_reset_transport_header(skb);
                return 0;
        }
index 52c04f0ac498123becfdc30af5a90f1b2291934d..9e254de7462fb86bb053353dfaa2715a369a7994 100644 (file)
@@ -233,8 +233,12 @@ static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
        rt = pol_lookup_func(lookup,
                             net, table, flp6, arg->lookup_data, flags);
        if (rt != net->ipv6.ip6_null_entry) {
+               struct inet6_dev *idev = ip6_dst_idev(&rt->dst);
+
+               if (!idev)
+                       goto again;
                err = fib6_rule_saddr(net, rule, flags, flp6,
-                                     ip6_dst_idev(&rt->dst)->dev);
+                                     idev->dev);
 
                if (err == -EAGAIN)
                        goto again;
index b41e35af69ea2835aa47d6ca01d9b109d4092462..c8b909a9904f321b91c9cfef46da9bb491c18a7d 100644 (file)
@@ -237,6 +237,7 @@ INDIRECT_CALLABLE_SCOPE struct sk_buff *ipv6_gro_receive(struct list_head *head,
                goto out;
 
        skb_set_network_header(skb, off);
+       NAPI_GRO_CB(skb)->inner_network_offset = off;
 
        flush += ntohs(iph->payload_len) != skb->len - hlen;
 
index b9dd3a66e4236fbf67af75c5f98c921b38c18bf6..97b0788b31baeb07d90070cb74c245002e50890d 100644 (file)
@@ -234,7 +234,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
        skb->protocol = htons(ETH_P_IPV6);
        skb->dev = dev;
 
-       if (unlikely(READ_ONCE(idev->cnf.disable_ipv6))) {
+       if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) {
                IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
                kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
                return 0;
@@ -1933,7 +1933,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
                u8 icmp6_type;
 
                if (sk->sk_socket->type == SOCK_RAW &&
-                  !inet_test_bit(HDRINCL, sk))
+                  !(fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH))
                        icmp6_type = fl6->fl6_icmp_type;
                else
                        icmp6_type = icmp6_hdr(skb)->icmp6_type;
index 1a4cccdd40c9ca44675cea5f5c2a08724ccb2d75..8f7aa8bac1e7b1eb330e4a6a9086b88e509886be 100644 (file)
@@ -272,7 +272,8 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
 struct sock *udp6_lib_lookup_skb(const struct sk_buff *skb,
                                 __be16 sport, __be16 dport)
 {
-       const struct ipv6hdr *iph = ipv6_hdr(skb);
+       const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
+       const struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + offset);
        struct net *net = dev_net(skb->dev);
        int iif, sdif;
 
index bbd347de00b450bb3ecbbfa41c4dab9d36bb79d9..b41152dd424697a9fc3cef13fbb430de49dcb913 100644 (file)
@@ -164,7 +164,8 @@ flush:
 
 INDIRECT_CALLABLE_SCOPE int udp6_gro_complete(struct sk_buff *skb, int nhoff)
 {
-       const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+       const u16 offset = NAPI_GRO_CB(skb)->network_offsets[skb->encapsulation];
+       const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + offset);
        struct udphdr *uh = (struct udphdr *)(skb->data + nhoff);
 
        /* do fraglist only if there is no outer UDP encap (or we already processed it) */
index a17d783dc7c0d7de6695e1ccec3a7b3a87f31e88..c6b8e132e10a32bf707ed8a5663d9182c1707903 100644 (file)
@@ -58,7 +58,11 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
        skb_postpush_rcsum(skb, skb_network_header(skb), nhlen);
 
        if (xo && (xo->flags & XFRM_GRO)) {
-               skb_mac_header_rebuild(skb);
+               /* The full l2 header needs to be preserved so that re-injecting the packet at l2
+                * works correctly in the presence of vlan tags.
+                */
+               skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
+               skb_reset_network_header(skb);
                skb_reset_transport_header(skb);
                return 0;
        }
index 39e487ccc46881b2ede597672b0e3df63ba8b05a..8ba00ad433c21bfc8f6566bed1360cb8e4cf4944 100644 (file)
@@ -127,6 +127,9 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
        /* checksums verified by L2TP */
        skb->ip_summed = CHECKSUM_NONE;
 
+       /* drop outer flow-hash */
+       skb_clear_hash(skb);
+
        skb_dst_drop(skb);
        nf_reset_ct(skb);
 
index 13fe0748dde83804daa160af50827dfc899fc426..2963ba84e2ee4baf55ad06568568c6605f1ba367 100644 (file)
@@ -96,6 +96,43 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
 }
 
 #ifdef CONFIG_SYSCTL
+static int mptcp_set_scheduler(const struct net *net, const char *name)
+{
+       struct mptcp_pernet *pernet = mptcp_get_pernet(net);
+       struct mptcp_sched_ops *sched;
+       int ret = 0;
+
+       rcu_read_lock();
+       sched = mptcp_sched_find(name);
+       if (sched)
+               strscpy(pernet->scheduler, name, MPTCP_SCHED_NAME_MAX);
+       else
+               ret = -ENOENT;
+       rcu_read_unlock();
+
+       return ret;
+}
+
+static int proc_scheduler(struct ctl_table *ctl, int write,
+                         void *buffer, size_t *lenp, loff_t *ppos)
+{
+       const struct net *net = current->nsproxy->net_ns;
+       char val[MPTCP_SCHED_NAME_MAX];
+       struct ctl_table tbl = {
+               .data = val,
+               .maxlen = MPTCP_SCHED_NAME_MAX,
+       };
+       int ret;
+
+       strscpy(val, mptcp_get_scheduler(net), MPTCP_SCHED_NAME_MAX);
+
+       ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
+       if (write && ret == 0)
+               ret = mptcp_set_scheduler(net, val);
+
+       return ret;
+}
+
 static struct ctl_table mptcp_sysctl_table[] = {
        {
                .procname = "enabled",
@@ -148,7 +185,7 @@ static struct ctl_table mptcp_sysctl_table[] = {
                .procname = "scheduler",
                .maxlen = MPTCP_SCHED_NAME_MAX,
                .mode = 0644,
-               .proc_handler = proc_dostring,
+               .proc_handler = proc_scheduler,
        },
        {
                .procname = "close_timeout",
index 7e74b812e366ae311f52615e9b304d6fe8b924b8..965eb69dc5de32b0d0ec01e5270b20a4fcb436b3 100644 (file)
@@ -3723,6 +3723,9 @@ static int mptcp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_TOKENFALLBACKINIT);
                mptcp_subflow_early_fallback(msk, subflow);
        }
+
+       WRITE_ONCE(msk->write_seq, subflow->idsn);
+       WRITE_ONCE(msk->snd_nxt, subflow->idsn);
        if (likely(!__mptcp_check_fallback(msk)))
                MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVE);
 
index 0d26c8ec9993ea18af0beeeff5ac1a8cd3ef72f6..b133dc55304cebf412b3df8959d609cb12ec88f5 100644 (file)
@@ -1518,6 +1518,7 @@ static void nci_rx_work(struct work_struct *work)
 
                if (!nci_plen(skb->data)) {
                        kfree_skb(skb);
+                       kcov_remote_stop();
                        break;
                }
 
index f4a38bd6a7e04f5944f8fa3d7f3cdc43caffed41..bfb7758063f315f4d13a6c17f8b01739933a6cf3 100644 (file)
@@ -77,13 +77,15 @@ EXPORT_SYMBOL_GPL(nsh_pop);
 static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
                                       netdev_features_t features)
 {
+       unsigned int outer_hlen, mac_len, nsh_len;
        struct sk_buff *segs = ERR_PTR(-EINVAL);
        u16 mac_offset = skb->mac_header;
-       unsigned int nsh_len, mac_len;
-       __be16 proto;
+       __be16 outer_proto, proto;
 
        skb_reset_network_header(skb);
 
+       outer_proto = skb->protocol;
+       outer_hlen = skb_mac_header_len(skb);
        mac_len = skb->mac_len;
 
        if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
@@ -113,10 +115,10 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
        }
 
        for (skb = segs; skb; skb = skb->next) {
-               skb->protocol = htons(ETH_P_NSH);
-               __skb_push(skb, nsh_len);
-               skb->mac_header = mac_offset;
-               skb->network_header = skb->mac_header + mac_len;
+               skb->protocol = outer_proto;
+               __skb_push(skb, nsh_len + outer_hlen);
+               skb_reset_mac_header(skb);
+               skb_set_network_header(skb, outer_hlen);
                skb->mac_len = mac_len;
        }
 
index 59aebe29689077bfa77d37516aea4617fe3b8a50..dd4c7e9a634fbe29645107de04a90688cdfb1a01 100644 (file)
@@ -193,7 +193,7 @@ void rtm_phonet_notify(int event, struct net_device *dev, u8 dst)
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+       skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct rtmsg)) +
                        nla_total_size(1) + nla_total_size(4), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
index 08c0a32db8c746f095b64c19b54ba6b2c1c815b2..08de24658f4fa9679cb489f7f889d9824ca73479 100644 (file)
@@ -697,7 +697,7 @@ struct rxrpc_call {
         * packets) rather than bytes.
         */
 #define RXRPC_TX_SMSS          RXRPC_JUMBO_DATALEN
-#define RXRPC_MIN_CWND         (RXRPC_TX_SMSS > 2190 ? 2 : RXRPC_TX_SMSS > 1095 ? 3 : 4)
+#define RXRPC_MIN_CWND         4
        u8                      cong_cwnd;      /* Congestion window size */
        u8                      cong_extra;     /* Extra to send for congestion management */
        u8                      cong_ssthresh;  /* Slow-start threshold */
index 01fa71e8b1f72c3c98fb6ca8657b8b8ab9e4b465..f9e983a12c1492261d87773b5a118431dafd406f 100644 (file)
@@ -174,12 +174,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
        call->rx_winsize = rxrpc_rx_window_size;
        call->tx_winsize = 16;
 
-       if (RXRPC_TX_SMSS > 2190)
-               call->cong_cwnd = 2;
-       else if (RXRPC_TX_SMSS > 1095)
-               call->cong_cwnd = 3;
-       else
-               call->cong_cwnd = 4;
+       call->cong_cwnd = RXRPC_MIN_CWND;
        call->cong_ssthresh = RXRPC_TX_MAX_WINDOW;
 
        call->rxnet = rxnet;
index 0af4642aeec4bcba890cfe0723b4ae001b378cf8..1539d315afe74ace265dd7ac32ffc7031d0b2323 100644 (file)
@@ -119,18 +119,13 @@ struct rxrpc_connection *rxrpc_find_client_connection_rcu(struct rxrpc_local *lo
        switch (srx->transport.family) {
        case AF_INET:
                if (peer->srx.transport.sin.sin_port !=
-                   srx->transport.sin.sin_port ||
-                   peer->srx.transport.sin.sin_addr.s_addr !=
-                   srx->transport.sin.sin_addr.s_addr)
+                   srx->transport.sin.sin_port)
                        goto not_found;
                break;
 #ifdef CONFIG_AF_RXRPC_IPV6
        case AF_INET6:
                if (peer->srx.transport.sin6.sin6_port !=
-                   srx->transport.sin6.sin6_port ||
-                   memcmp(&peer->srx.transport.sin6.sin6_addr,
-                          &srx->transport.sin6.sin6_addr,
-                          sizeof(struct in6_addr)) != 0)
+                   srx->transport.sin6.sin6_port)
                        goto not_found;
                break;
 #endif
index 3dedb8c0618ca6c79075184b88dbe5e0078e7548..16d49a861dbb582fa5055101f4e536bb5b70f71d 100644 (file)
@@ -9,6 +9,17 @@
 
 #include "ar-internal.h"
 
+/* Override priority when generating ACKs for received DATA */
+static const u8 rxrpc_ack_priority[RXRPC_ACK__INVALID] = {
+       [RXRPC_ACK_IDLE]                = 1,
+       [RXRPC_ACK_DELAY]               = 2,
+       [RXRPC_ACK_REQUESTED]           = 3,
+       [RXRPC_ACK_DUPLICATE]           = 4,
+       [RXRPC_ACK_EXCEEDS_WINDOW]      = 5,
+       [RXRPC_ACK_NOSPACE]             = 6,
+       [RXRPC_ACK_OUT_OF_SEQUENCE]     = 7,
+};
+
 static void rxrpc_proto_abort(struct rxrpc_call *call, rxrpc_seq_t seq,
                              enum rxrpc_abort_reason why)
 {
@@ -365,7 +376,7 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
  * Process a DATA packet.
  */
 static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
-                                bool *_notify)
+                                bool *_notify, rxrpc_serial_t *_ack_serial, int *_ack_reason)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        struct sk_buff *oos;
@@ -418,8 +429,6 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
                /* Send an immediate ACK if we fill in a hole */
                else if (!skb_queue_empty(&call->rx_oos_queue))
                        ack_reason = RXRPC_ACK_DELAY;
-               else
-                       call->ackr_nr_unacked++;
 
                window++;
                if (after(window, wtop)) {
@@ -497,12 +506,16 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
        }
 
 send_ack:
-       if (ack_reason >= 0)
-               rxrpc_send_ACK(call, ack_reason, serial,
-                              rxrpc_propose_ack_input_data);
-       else
-               rxrpc_propose_delay_ACK(call, serial,
-                                       rxrpc_propose_ack_input_data);
+       if (ack_reason >= 0) {
+               if (rxrpc_ack_priority[ack_reason] > rxrpc_ack_priority[*_ack_reason]) {
+                       *_ack_serial = serial;
+                       *_ack_reason = ack_reason;
+               } else if (rxrpc_ack_priority[ack_reason] == rxrpc_ack_priority[*_ack_reason] &&
+                          ack_reason == RXRPC_ACK_REQUESTED) {
+                       *_ack_serial = serial;
+                       *_ack_reason = ack_reason;
+               }
+       }
 }
 
 /*
@@ -513,9 +526,11 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
        struct rxrpc_jumbo_header jhdr;
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb), *jsp;
        struct sk_buff *jskb;
+       rxrpc_serial_t ack_serial = 0;
        unsigned int offset = sizeof(struct rxrpc_wire_header);
        unsigned int len = skb->len - offset;
        bool notify = false;
+       int ack_reason = 0;
 
        while (sp->hdr.flags & RXRPC_JUMBO_PACKET) {
                if (len < RXRPC_JUMBO_SUBPKTLEN)
@@ -535,7 +550,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
                jsp = rxrpc_skb(jskb);
                jsp->offset = offset;
                jsp->len = RXRPC_JUMBO_DATALEN;
-               rxrpc_input_data_one(call, jskb, &notify);
+               rxrpc_input_data_one(call, jskb, &notify, &ack_serial, &ack_reason);
                rxrpc_free_skb(jskb, rxrpc_skb_put_jumbo_subpacket);
 
                sp->hdr.flags = jhdr.flags;
@@ -548,7 +563,16 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
 
        sp->offset = offset;
        sp->len    = len;
-       rxrpc_input_data_one(call, skb, &notify);
+       rxrpc_input_data_one(call, skb, &notify, &ack_serial, &ack_reason);
+
+       if (ack_reason > 0) {
+               rxrpc_send_ACK(call, ack_reason, ack_serial,
+                              rxrpc_propose_ack_input_data);
+       } else {
+               call->ackr_nr_unacked++;
+               rxrpc_propose_delay_ACK(call, sp->hdr.serial,
+                                       rxrpc_propose_ack_input_data);
+       }
        if (notify) {
                trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
                rxrpc_notify_socket(call);
@@ -685,9 +709,6 @@ static void rxrpc_input_ack_trailer(struct rxrpc_call *call, struct sk_buff *skb
                call->tx_winsize = rwind;
        }
 
-       if (call->cong_ssthresh > rwind)
-               call->cong_ssthresh = rwind;
-
        mtu = min(ntohl(trailer->maxMTU), ntohl(trailer->ifMTU));
 
        peer = call->peer;
index f2701068ed9e4ce48c52848901e983f21de459c7..6716c021a532e184e5e09e50c958e4128d9f97bf 100644 (file)
@@ -19,7 +19,7 @@ static int none_init_connection_security(struct rxrpc_connection *conn,
  */
 static struct rxrpc_txbuf *none_alloc_txbuf(struct rxrpc_call *call, size_t remain, gfp_t gfp)
 {
-       return rxrpc_alloc_data_txbuf(call, min_t(size_t, remain, RXRPC_JUMBO_DATALEN), 0, gfp);
+       return rxrpc_alloc_data_txbuf(call, min_t(size_t, remain, RXRPC_JUMBO_DATALEN), 1, gfp);
 }
 
 static int none_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
index f1a68270862db9715801594e754f48d7a77d822d..48a1475e6b0634cc806641f4d5a134684d1c56cf 100644 (file)
@@ -155,7 +155,7 @@ static struct rxrpc_txbuf *rxkad_alloc_txbuf(struct rxrpc_call *call, size_t rem
        switch (call->conn->security_level) {
        default:
                space = min_t(size_t, remain, RXRPC_JUMBO_DATALEN);
-               return rxrpc_alloc_data_txbuf(call, space, 0, gfp);
+               return rxrpc_alloc_data_txbuf(call, space, 1, gfp);
        case RXRPC_SECURITY_AUTH:
                shdr = sizeof(struct rxkad_level1_hdr);
                break;
index e0679658d9de0e62edd777cad0b7e4281cfe2384..c3913d8a50d340bff0636f144f6c65afbe755cdd 100644 (file)
@@ -21,20 +21,20 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_
 {
        struct rxrpc_wire_header *whdr;
        struct rxrpc_txbuf *txb;
-       size_t total, hoff = 0;
+       size_t total, hoff;
        void *buf;
 
        txb = kmalloc(sizeof(*txb), gfp);
        if (!txb)
                return NULL;
 
-       if (data_align)
-               hoff = round_up(sizeof(*whdr), data_align) - sizeof(*whdr);
+       hoff = round_up(sizeof(*whdr), data_align) - sizeof(*whdr);
        total = hoff + sizeof(*whdr) + data_size;
 
+       data_align = umax(data_align, L1_CACHE_BYTES);
        mutex_lock(&call->conn->tx_data_alloc_lock);
-       buf = __page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp,
-                                     ~(data_align - 1) & ~(L1_CACHE_BYTES - 1));
+       buf = page_frag_alloc_align(&call->conn->tx_data_alloc, total, gfp,
+                                   data_align);
        mutex_unlock(&call->conn->tx_data_alloc_lock);
        if (!buf) {
                kfree(txb);
index 97704a9e84c701f55750ecd51fa872a726a826ac..9297dc20bfe23718d8031d78185171bb7ce5c31a 100644 (file)
@@ -209,13 +209,18 @@ int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr,
        if (IS_ERR(rt))
                goto out;
        if (rt->rt_uses_gateway && rt->rt_gw_family != AF_INET)
-               goto out;
-       neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &fl4.daddr);
-       if (neigh) {
-               memcpy(nexthop_mac, neigh->ha, ETH_ALEN);
-               *uses_gateway = rt->rt_uses_gateway;
-               return 0;
-       }
+               goto out_rt;
+       neigh = dst_neigh_lookup(&rt->dst, &fl4.daddr);
+       if (!neigh)
+               goto out_rt;
+       memcpy(nexthop_mac, neigh->ha, ETH_ALEN);
+       *uses_gateway = rt->rt_uses_gateway;
+       neigh_release(neigh);
+       ip_rt_put(rt);
+       return 0;
+
+out_rt:
+       ip_rt_put(rt);
 out:
        return -ENOENT;
 }
index bb9b747d58a1afac3619b80cff3e8196e36d96c3..ce18716491c8fed0cbe234f2044e3539c3bac6a3 100644 (file)
@@ -2664,6 +2664,7 @@ static void xs_tcp_tls_setup_socket(struct work_struct *work)
                .xprtsec        = {
                        .policy         = RPC_XPRTSEC_NONE,
                },
+               .stats          = upper_clnt->cl_stats,
        };
        unsigned int pflags = current->flags;
        struct rpc_clnt *lower_clnt;
index 5c9fd4791c4ba1976f1d3d7fcb9ad458df1436f7..76284fc538ebdd38d52c879bd4fc58c84abc6371 100644 (file)
@@ -142,9 +142,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
        if (fragid == FIRST_FRAGMENT) {
                if (unlikely(head))
                        goto err;
-               *buf = NULL;
                if (skb_has_frag_list(frag) && __skb_linearize(frag))
                        goto err;
+               *buf = NULL;
                frag = skb_unshare(frag, GFP_ATOMIC);
                if (unlikely(!frag))
                        goto err;
@@ -156,6 +156,11 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
        if (!head)
                goto err;
 
+       /* Either the input skb ownership is transferred to headskb
+        * or the input skb is freed, clear the reference to avoid
+        * bad access on error path.
+        */
+       *buf = NULL;
        if (skb_try_coalesce(head, frag, &headstolen, &delta)) {
                kfree_skb_partial(frag, headstolen);
        } else {
@@ -179,7 +184,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
                *headbuf = NULL;
                return 1;
        }
-       *buf = NULL;
        return 0;
 err:
        kfree_skb(*buf);
index 161f535c8b9495b01f6d9689e14c40e5c0885968..3a2982a72a6b8c1f91708d85785d4c6d8440d3a1 100644 (file)
@@ -389,11 +389,15 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
  */
 static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 {
+       struct xfrm_offload *xo = xfrm_offload(skb);
        int ihl = skb->data - skb_transport_header(skb);
 
        if (skb->transport_header != skb->network_header) {
                memmove(skb_transport_header(skb),
                        skb_network_header(skb), ihl);
+               if (xo)
+                       xo->orig_mac_len =
+                               skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
                skb->network_header = skb->transport_header;
        }
        ip_hdr(skb)->tot_len = htons(skb->len + ihl);
@@ -404,11 +408,15 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 {
 #if IS_ENABLED(CONFIG_IPV6)
+       struct xfrm_offload *xo = xfrm_offload(skb);
        int ihl = skb->data - skb_transport_header(skb);
 
        if (skb->transport_header != skb->network_header) {
                memmove(skb_transport_header(skb),
                        skb_network_header(skb), ihl);
+               if (xo)
+                       xo->orig_mac_len =
+                               skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
                skb->network_header = skb->transport_header;
        }
        ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -
index 6affe5cd85d8f14fb1689b830422eaea56d0dafc..53d8fabfa68580a24359a7ef3bb8f82a76715c98 100644 (file)
@@ -3593,6 +3593,8 @@ xfrm_policy *xfrm_in_fwd_icmp(struct sk_buff *skb,
                        return pol;
 
                pol = xfrm_policy_lookup(net, &fl1, family, XFRM_POLICY_FWD, if_id);
+               if (IS_ERR(pol))
+                       pol = NULL;
        }
 
        return pol;
index 846e6ab9d5a9b660fd871a13c8f984260a1b105a..86a125c4243cb2e5eba7f906417be4602bd8b738 100644 (file)
@@ -175,7 +175,6 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
        mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \
        OBJTREE=$(abspath $(objtree)) \
        $(RUSTDOC) --test $(rust_flags) \
-               @$(objtree)/include/generated/rustc_cfg \
                -L$(objtree)/$(obj) --extern alloc --extern kernel \
                --extern build_error --extern macros \
                --extern bindings --extern uapi \
index 424257284d167b5caa23ed880353abbd7ef2de34..09004b56fb65c7aadcf857a41086159b6fa1f550 100644 (file)
@@ -1292,8 +1292,15 @@ impl_zeroable! {
     i8, i16, i32, i64, i128, isize,
     f32, f64,
 
-    // SAFETY: These are ZSTs, there is nothing to zero.
-    {<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, Infallible, (),
+    // Note: do not add uninhabited types (such as `!` or `core::convert::Infallible`) to this list;
+    // creating an instance of an uninhabited type is immediate undefined behavior. For more on
+    // uninhabited/empty types, consult The Rustonomicon:
+    // <https://doc.rust-lang.org/stable/nomicon/exotic-sizes.html#empty-types>. The Rust Reference
+    // also has information on undefined behavior:
+    // <https://doc.rust-lang.org/stable/reference/behavior-considered-undefined.html>.
+    //
+    // SAFETY: These are inhabited ZSTs; there is nothing to zero and a valid value exists.
+    {<T: ?Sized>} PhantomData<T>, core::marker::PhantomPinned, (),
 
     // SAFETY: Type is allowed to take any value, including all zeros.
     {<T>} MaybeUninit<T>,
index be68d5e567b1a1f7a181e08586ed05f2ca008cd6..6858e2f8a3ed976ce644eb2f8ea4d9fbb40edc3b 100644 (file)
@@ -65,7 +65,7 @@ const __LOG_PREFIX: &[u8] = b"rust_kernel\0";
 /// The top level entrypoint to implementing a kernel module.
 ///
 /// For any teardown or cleanup operations, your type may implement [`Drop`].
-pub trait Module: Sized + Sync {
+pub trait Module: Sized + Sync + Send {
     /// Called at module initialization time.
     ///
     /// Use this method to perform whatever setup or registration your module
index 96e09c6e8530b4d108e6a664e93ab41436c797dc..265d0e1c13710a53a9f9d0b5af12b24402eb4741 100644 (file)
@@ -640,6 +640,10 @@ pub struct Registration {
     drivers: Pin<&'static mut [DriverVTable]>,
 }
 
+// SAFETY: The only action allowed in a `Registration` instance is dropping it, which is safe to do
+// from any thread because `phy_drivers_unregister` can be called from any thread context.
+unsafe impl Send for Registration {}
+
 impl Registration {
     /// Registers a PHY driver.
     pub fn register(
index f489f3157383239d81c0badd5085627d431e6c4c..520eae5fd792810069d8018d922f6c56c0bcc101 100644 (file)
@@ -35,18 +35,6 @@ use proc_macro::TokenStream;
 ///     author: "Rust for Linux Contributors",
 ///     description: "My very own kernel module!",
 ///     license: "GPL",
-///     params: {
-///        my_i32: i32 {
-///            default: 42,
-///            permissions: 0o000,
-///            description: "Example of i32",
-///        },
-///        writeable_i32: i32 {
-///            default: 42,
-///            permissions: 0o644,
-///            description: "Example of i32",
-///        },
-///    },
 /// }
 ///
 /// struct MyModule;
index 27979e582e4b943b963a88ee7cecdea4f345b83f..acd0393b509574b0989bedcf1ed244532ab63a29 100644 (file)
@@ -199,17 +199,6 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
             /// Used by the printing macros, e.g. [`info!`].
             const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
 
-            /// The \"Rust loadable module\" mark.
-            //
-            // This may be best done another way later on, e.g. as a new modinfo
-            // key or a new section. For the moment, keep it simple.
-            #[cfg(MODULE)]
-            #[doc(hidden)]
-            #[used]
-            static __IS_RUST_MODULE: () = ();
-
-            static mut __MOD: Option<{type_}> = None;
-
             // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
             // freed until the module is unloaded.
             #[cfg(MODULE)]
@@ -221,81 +210,132 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
                 kernel::ThisModule::from_ptr(core::ptr::null_mut())
             }};
 
-            // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
-            /// # Safety
-            ///
-            /// This function must not be called after module initialization, because it may be
-            /// freed after that completes.
-            #[cfg(MODULE)]
-            #[doc(hidden)]
-            #[no_mangle]
-            #[link_section = \".init.text\"]
-            pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
-                __init()
-            }}
-
-            #[cfg(MODULE)]
-            #[doc(hidden)]
-            #[no_mangle]
-            pub extern \"C\" fn cleanup_module() {{
-                __exit()
-            }}
+            // Double nested modules, since then nobody can access the public items inside.
+            mod __module_init {{
+                mod __module_init {{
+                    use super::super::{type_};
+
+                    /// The \"Rust loadable module\" mark.
+                    //
+                    // This may be best done another way later on, e.g. as a new modinfo
+                    // key or a new section. For the moment, keep it simple.
+                    #[cfg(MODULE)]
+                    #[doc(hidden)]
+                    #[used]
+                    static __IS_RUST_MODULE: () = ();
+
+                    static mut __MOD: Option<{type_}> = None;
+
+                    // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
+                    /// # Safety
+                    ///
+                    /// This function must not be called after module initialization, because it may be
+                    /// freed after that completes.
+                    #[cfg(MODULE)]
+                    #[doc(hidden)]
+                    #[no_mangle]
+                    #[link_section = \".init.text\"]
+                    pub unsafe extern \"C\" fn init_module() -> core::ffi::c_int {{
+                        // SAFETY: This function is inaccessible to the outside due to the double
+                        // module wrapping it. It is called exactly once by the C side via its
+                        // unique name.
+                        unsafe {{ __init() }}
+                    }}
 
-            // Built-in modules are initialized through an initcall pointer
-            // and the identifiers need to be unique.
-            #[cfg(not(MODULE))]
-            #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
-            #[doc(hidden)]
-            #[link_section = \"{initcall_section}\"]
-            #[used]
-            pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
+                    #[cfg(MODULE)]
+                    #[doc(hidden)]
+                    #[no_mangle]
+                    pub extern \"C\" fn cleanup_module() {{
+                        // SAFETY:
+                        // - This function is inaccessible to the outside due to the double
+                        //   module wrapping it. It is called exactly once by the C side via its
+                        //   unique name,
+                        // - furthermore it is only called after `init_module` has returned `0`
+                        //   (which delegates to `__init`).
+                        unsafe {{ __exit() }}
+                    }}
 
-            #[cfg(not(MODULE))]
-            #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
-            core::arch::global_asm!(
-                r#\".section \"{initcall_section}\", \"a\"
-                __{name}_initcall:
-                    .long   __{name}_init - .
-                    .previous
-                \"#
-            );
+                    // Built-in modules are initialized through an initcall pointer
+                    // and the identifiers need to be unique.
+                    #[cfg(not(MODULE))]
+                    #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
+                    #[doc(hidden)]
+                    #[link_section = \"{initcall_section}\"]
+                    #[used]
+                    pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
+
+                    #[cfg(not(MODULE))]
+                    #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
+                    core::arch::global_asm!(
+                        r#\".section \"{initcall_section}\", \"a\"
+                        __{name}_initcall:
+                            .long   __{name}_init - .
+                            .previous
+                        \"#
+                    );
+
+                    #[cfg(not(MODULE))]
+                    #[doc(hidden)]
+                    #[no_mangle]
+                    pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
+                        // SAFETY: This function is inaccessible to the outside due to the double
+                        // module wrapping it. It is called exactly once by the C side via its
+                        // placement above in the initcall section.
+                        unsafe {{ __init() }}
+                    }}
 
-            #[cfg(not(MODULE))]
-            #[doc(hidden)]
-            #[no_mangle]
-            pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
-                __init()
-            }}
+                    #[cfg(not(MODULE))]
+                    #[doc(hidden)]
+                    #[no_mangle]
+                    pub extern \"C\" fn __{name}_exit() {{
+                        // SAFETY:
+                        // - This function is inaccessible to the outside due to the double
+                        //   module wrapping it. It is called exactly once by the C side via its
+                        //   unique name,
+                        // - furthermore it is only called after `__{name}_init` has returned `0`
+                        //   (which delegates to `__init`).
+                        unsafe {{ __exit() }}
+                    }}
 
-            #[cfg(not(MODULE))]
-            #[doc(hidden)]
-            #[no_mangle]
-            pub extern \"C\" fn __{name}_exit() {{
-                __exit()
-            }}
+                    /// # Safety
+                    ///
+                    /// This function must only be called once.
+                    unsafe fn __init() -> core::ffi::c_int {{
+                        match <{type_} as kernel::Module>::init(&super::super::THIS_MODULE) {{
+                            Ok(m) => {{
+                                // SAFETY: No data race, since `__MOD` can only be accessed by this
+                                // module and there only `__init` and `__exit` access it. These
+                                // functions are only called once and `__exit` cannot be called
+                                // before or during `__init`.
+                                unsafe {{
+                                    __MOD = Some(m);
+                                }}
+                                return 0;
+                            }}
+                            Err(e) => {{
+                                return e.to_errno();
+                            }}
+                        }}
+                    }}
 
-            fn __init() -> core::ffi::c_int {{
-                match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
-                    Ok(m) => {{
+                    /// # Safety
+                    ///
+                    /// This function must
+                    /// - only be called once,
+                    /// - be called after `__init` has been called and returned `0`.
+                    unsafe fn __exit() {{
+                        // SAFETY: No data race, since `__MOD` can only be accessed by this module
+                        // and there only `__init` and `__exit` access it. These functions are only
+                        // called once and `__init` was already called.
                         unsafe {{
-                            __MOD = Some(m);
+                            // Invokes `drop()` on `__MOD`, which should be used for cleanup.
+                            __MOD = None;
                         }}
-                        return 0;
-                    }}
-                    Err(e) => {{
-                        return e.to_errno();
                     }}
-                }}
-            }}
 
-            fn __exit() {{
-                unsafe {{
-                    // Invokes `drop()` on `__MOD`, which should be used for cleanup.
-                    __MOD = None;
+                    {modinfo}
                 }}
             }}
-
-            {modinfo}
         ",
         type_ = info.type_,
         name = info.name,
index baf86c0880b6d7d548f4a6a21cd6305acc717078..533a7799fdfe6d1848ab6c5c6f7ef67990f8c9b0 100644 (file)
@@ -273,7 +273,7 @@ rust_common_cmd = \
        -Zallow-features=$(rust_allowed_features) \
        -Zcrate-attr=no_std \
        -Zcrate-attr='feature($(rust_allowed_features))' \
-       --extern alloc --extern kernel \
+       -Zunstable-options --extern force:alloc --extern kernel \
        --crate-type rlib -L $(objtree)/rust/ \
        --crate-name $(basename $(notdir $@)) \
        --sysroot=/dev/null \
diff --git a/scripts/check-variable-fonts.sh b/scripts/check-variable-fonts.sh
new file mode 100755 (executable)
index 0000000..ce63f0a
--- /dev/null
@@ -0,0 +1,115 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) Akira Yokosawa, 2024
+#
+# For "make pdfdocs", reports of build errors of translations.pdf started
+# arriving early 2024 [1, 2].  It turned out that Fedora and openSUSE
+# tumbleweed have started deploying variable-font [3] format of "Noto CJK"
+# fonts [4, 5].  For PDF, a LaTeX package named xeCJK is used for CJK
+# (Chinese, Japanese, Korean) pages.  xeCJK requires XeLaTeX/XeTeX, which
+# does not (and likely never will) understand variable fonts for historical
+# reasons.
+#
+# The build error happens even when both of variable- and non-variable-format
+# fonts are found on the build system.  To make matters worse, Fedora enlists
+# variable "Noto CJK" fonts in the requirements of langpacks-ja, -ko, -zh_CN,
+# -zh_TW, etc.  Hence developers who have interest in CJK pages are more
+# likely to encounter the build errors.
+#
+# This script is invoked from the error path of "make pdfdocs" and emits
+# suggestions if variable-font files of "Noto CJK" fonts are in the list of
+# fonts accessible from XeTeX.
+#
+# References:
+# [1]: https://lore.kernel.org/r/8734tqsrt7.fsf@meer.lwn.net/
+# [2]: https://lore.kernel.org/r/1708585803.600323099@f111.i.mail.ru/
+# [3]: https://en.wikipedia.org/wiki/Variable_font
+# [4]: https://fedoraproject.org/wiki/Changes/Noto_CJK_Variable_Fonts
+# [5]: https://build.opensuse.org/request/show/1157217
+#
+#===========================================================================
+# Workarounds for building translations.pdf
+#===========================================================================
+#
+# * Denylist "variable font" Noto CJK fonts.
+#   - Create $HOME/deny-vf/fontconfig/fonts.conf from template below, with
+#     tweaks if necessary.  Remove leading "# ".
+#   - Path of fontconfig/fonts.conf can be overridden by setting an env
+#     variable FONTS_CONF_DENY_VF.
+#
+#     * Template:
+# -----------------------------------------------------------------
+# <?xml version="1.0"?>
+# <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
+# <fontconfig>
+# <!--
+#   Ignore variable-font glob (not to break xetex)
+# -->
+#     <selectfont>
+#         <rejectfont>
+#             <!--
+#                 for Fedora
+#             -->
+#             <glob>/usr/share/fonts/google-noto-*-cjk-vf-fonts</glob>
+#             <!--
+#                 for openSUSE tumbleweed
+#             -->
+#             <glob>/usr/share/fonts/truetype/Noto*CJK*-VF.otf</glob>
+#         </rejectfont>
+#     </selectfont>
+# </fontconfig>
+# -----------------------------------------------------------------
+#
+#     The denylisting is activated for "make pdfdocs".
+#
+# * For skipping CJK pages in PDF
+#   - Uninstall texlive-xecjk.
+#     Denylisting is not needed in this case.
+#
+# * For printing CJK pages in PDF
+#   - Need non-variable "Noto CJK" fonts.
+#     * Fedora
+#       - google-noto-sans-cjk-fonts
+#       - google-noto-serif-cjk-fonts
+#     * openSUSE tumbleweed
+#       - Non-variable "Noto CJK" fonts are not available as distro packages
+#         as of April, 2024.  Fetch a set of font files from upstream Noto
+#         CJK Font released at:
+#           https://github.com/notofonts/noto-cjk/tree/main/Sans#super-otc
+#         and at:
+#           https://github.com/notofonts/noto-cjk/tree/main/Serif#super-otc
+#         , then uncompress and deploy them.
+#       - Remember to update fontconfig cache by running fc-cache.
+#
+# !!! Caution !!!
+#     Uninstalling "variable font" packages can be dangerous.
+#     They might be depended upon by other packages important for your work.
+#     Denylisting should be less invasive, as it is effective only while
+#     XeLaTeX runs in "make pdfdocs".
+
+# Default per-user fontconfig path (overridden by env variable)
+: ${FONTS_CONF_DENY_VF:=$HOME/deny-vf}
+
+export XDG_CONFIG_HOME=${FONTS_CONF_DENY_VF}
+
+notocjkvffonts=`fc-list : file family variable | \
+               grep 'variable=True' | \
+               grep -E -e 'Noto (Sans|Sans Mono|Serif) CJK' | \
+               sed -e 's/^/    /' -e 's/: Noto S.*$//' | sort | uniq`
+
+if [ "x$notocjkvffonts" != "x" ] ; then
+       echo '============================================================================='
+       echo 'XeTeX is confused by "variable font" files listed below:'
+       echo "$notocjkvffonts"
+       echo
+       echo 'For CJK pages in PDF, they need to be hidden from XeTeX by denylisting.'
+       echo 'Or, CJK pages can be skipped by uninstalling texlive-xecjk.'
+       echo
+       echo 'For more info on denylisting, other options, and variable font, see header'
+       echo 'comments of scripts/check-variable-fonts.sh.'
+       echo '============================================================================='
+fi
+
+# As this script is invoked from Makefile's error path, always error exit
+# regardless of whether any variable font is discovered or not.
+exit 1
index cb1be22afc65ffa9196b984c991133efffd0da3f..7962d0daa63865fe1aebc3b1d952d586949a2e00 100755 (executable)
@@ -62,7 +62,7 @@ my $anon_struct_union = 0;
 
 # match expressions used to find embedded type information
 my $type_constant = '\b``([^\`]+)``\b';
-my $type_constant2 = '\%([-_\w]+)';
+my $type_constant2 = '\%([-_*\w]+)';
 my $type_func = '(\w+)\(\)';
 my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
 my $type_param_ref = '([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
@@ -1151,7 +1151,8 @@ sub dump_struct($$) {
         # - first eat non-declaration parameters and rewrite for final match
         # - then remove macro, outer parens, and trailing semicolon
         $members =~ s/\bstruct_group\s*\(([^,]*,)/STRUCT_GROUP(/gos;
-        $members =~ s/\bstruct_group_(attr|tagged)\s*\(([^,]*,){2}/STRUCT_GROUP(/gos;
+        $members =~ s/\bstruct_group_attr\s*\(([^,]*,){2}/STRUCT_GROUP(/gos;
+        $members =~ s/\bstruct_group_tagged\s*\(([^,]*),([^,]*),/struct $1 $2; STRUCT_GROUP(/gos;
         $members =~ s/\b__struct_group\s*\(([^,]*,){3}/STRUCT_GROUP(/gos;
         $members =~ s/\bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;/$2/gos;
 
index 2f5b91da5afa9ea768caaf0c3e1d1e253fcdfc48..937294ff164fc8fc1ac3c1ed926ec5d1131a43ef 100644 (file)
@@ -601,11 +601,6 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
                    strstarts(symname, "_savevr_") ||
                    strcmp(symname, ".TOC.") == 0)
                        return 1;
-
-       if (info->hdr->e_machine == EM_S390)
-               /* Expoline thunks are linked on all kernel modules during final link of .ko */
-               if (strstarts(symname, "__s390_indirect_jump_r"))
-                       return 1;
        /* Do not ignore this symbol */
        return 0;
 }
index 4c781617ffe6afce5e856be98d896016f44bacf8..c1121f09854244f6189256fae1de542e73a02f85 100755 (executable)
@@ -514,6 +514,7 @@ sub give_mageia_hints()
 {
        my %map = (
                "python-sphinx"         => "python3-sphinx",
+               "yaml"                  => "python3-yaml",
                "virtualenv"            => "python3-virtualenv",
                "dot"                   => "graphviz",
                "convert"               => "ImageMagick",
@@ -557,10 +558,11 @@ sub give_mageia_hints()
 sub give_arch_linux_hints()
 {
        my %map = (
+               "yaml"                  => "python-yaml",
                "virtualenv"            => "python-virtualenv",
                "dot"                   => "graphviz",
                "convert"               => "imagemagick",
-               "xelatex"               => "texlive-bin",
+               "xelatex"               => "texlive-xetex",
                "latexmk"               => "texlive-core",
                "rsvg-convert"          => "extra/librsvg",
        );
@@ -587,6 +589,7 @@ sub give_arch_linux_hints()
 sub give_gentoo_hints()
 {
        my %map = (
+               "yaml"                  => "dev-python/pyyaml",
                "virtualenv"            => "dev-python/virtualenv",
                "dot"                   => "media-gfx/graphviz",
                "convert"               => "media-gfx/imagemagick",
index eaddaceda14eab077512f75081f102cf00157566..7d687b0962b14678ae1a1edc31973e7021700740 100644 (file)
@@ -155,14 +155,6 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
 
                security_key_free(key);
 
-               /* deal with the user's key tracking and quota */
-               if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
-                       spin_lock(&key->user->lock);
-                       key->user->qnkeys--;
-                       key->user->qnbytes -= key->quotalen;
-                       spin_unlock(&key->user->lock);
-               }
-
                atomic_dec(&key->user->nkeys);
                if (state != KEY_IS_UNINSTANTIATED)
                        atomic_dec(&key->user->nikeys);
index 5607900383298fa95997de8cbd9455db268af403..3d7d185019d30a8befd20dd8717f4350a949798c 100644 (file)
@@ -230,6 +230,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        struct key *key;
        size_t desclen, quotalen;
        int ret;
+       unsigned long irqflags;
 
        key = ERR_PTR(-EINVAL);
        if (!desc || !*desc)
@@ -259,7 +260,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
                unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
                        key_quota_root_maxbytes : key_quota_maxbytes;
 
-               spin_lock(&user->lock);
+               spin_lock_irqsave(&user->lock, irqflags);
                if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
                        if (user->qnkeys + 1 > maxkeys ||
                            user->qnbytes + quotalen > maxbytes ||
@@ -269,7 +270,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
 
                user->qnkeys++;
                user->qnbytes += quotalen;
-               spin_unlock(&user->lock);
+               spin_unlock_irqrestore(&user->lock, irqflags);
        }
 
        /* allocate and initialise the key and its description */
@@ -327,10 +328,10 @@ security_error:
        kfree(key->description);
        kmem_cache_free(key_jar, key);
        if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
-               spin_lock(&user->lock);
+               spin_lock_irqsave(&user->lock, irqflags);
                user->qnkeys--;
                user->qnbytes -= quotalen;
-               spin_unlock(&user->lock);
+               spin_unlock_irqrestore(&user->lock, irqflags);
        }
        key_user_put(user);
        key = ERR_PTR(ret);
@@ -340,10 +341,10 @@ no_memory_3:
        kmem_cache_free(key_jar, key);
 no_memory_2:
        if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
-               spin_lock(&user->lock);
+               spin_lock_irqsave(&user->lock, irqflags);
                user->qnkeys--;
                user->qnbytes -= quotalen;
-               spin_unlock(&user->lock);
+               spin_unlock_irqrestore(&user->lock, irqflags);
        }
        key_user_put(user);
 no_memory_1:
@@ -351,7 +352,7 @@ no_memory_1:
        goto error;
 
 no_quota:
-       spin_unlock(&user->lock);
+       spin_unlock_irqrestore(&user->lock, irqflags);
        key_user_put(user);
        key = ERR_PTR(-EDQUOT);
        goto error;
@@ -380,8 +381,9 @@ int key_payload_reserve(struct key *key, size_t datalen)
        if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
                unsigned maxbytes = uid_eq(key->user->uid, GLOBAL_ROOT_UID) ?
                        key_quota_root_maxbytes : key_quota_maxbytes;
+               unsigned long flags;
 
-               spin_lock(&key->user->lock);
+               spin_lock_irqsave(&key->user->lock, flags);
 
                if (delta > 0 &&
                    (key->user->qnbytes + delta > maxbytes ||
@@ -392,7 +394,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
                        key->user->qnbytes += delta;
                        key->quotalen += delta;
                }
-               spin_unlock(&key->user->lock);
+               spin_unlock_irqrestore(&key->user->lock, flags);
        }
 
        /* change the recorded data length if that didn't generate an error */
@@ -463,7 +465,8 @@ static int __key_instantiate_and_link(struct key *key,
                        if (authkey)
                                key_invalidate(authkey);
 
-                       key_set_expiry(key, prep->expiry);
+                       if (prep->expiry != TIME64_MAX)
+                               key_set_expiry(key, prep->expiry);
                }
        }
 
@@ -645,8 +648,18 @@ void key_put(struct key *key)
        if (key) {
                key_check(key);
 
-               if (refcount_dec_and_test(&key->usage))
+               if (refcount_dec_and_test(&key->usage)) {
+                       unsigned long flags;
+
+                       /* deal with the user's key tracking and quota */
+                       if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
+                               spin_lock_irqsave(&key->user->lock, flags);
+                               key->user->qnkeys--;
+                               key->user->qnbytes -= key->quotalen;
+                               spin_unlock_irqrestore(&key->user->lock, flags);
+                       }
                        schedule_work(&key_gc_work);
+               }
        }
 }
 EXPORT_SYMBOL(key_put);
index 10ba439968f744c61faf5ac0b86c6d3eb561b0b6..4bc3e9398ee3d9c6b35e5fce5a3aad5365197fe5 100644 (file)
@@ -954,6 +954,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
        long ret;
        kuid_t uid;
        kgid_t gid;
+       unsigned long flags;
 
        uid = make_kuid(current_user_ns(), user);
        gid = make_kgid(current_user_ns(), group);
@@ -1010,7 +1011,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
                        unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
                                key_quota_root_maxbytes : key_quota_maxbytes;
 
-                       spin_lock(&newowner->lock);
+                       spin_lock_irqsave(&newowner->lock, flags);
                        if (newowner->qnkeys + 1 > maxkeys ||
                            newowner->qnbytes + key->quotalen > maxbytes ||
                            newowner->qnbytes + key->quotalen <
@@ -1019,12 +1020,12 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
 
                        newowner->qnkeys++;
                        newowner->qnbytes += key->quotalen;
-                       spin_unlock(&newowner->lock);
+                       spin_unlock_irqrestore(&newowner->lock, flags);
 
-                       spin_lock(&key->user->lock);
+                       spin_lock_irqsave(&key->user->lock, flags);
                        key->user->qnkeys--;
                        key->user->qnbytes -= key->quotalen;
-                       spin_unlock(&key->user->lock);
+                       spin_unlock_irqrestore(&key->user->lock, flags);
                }
 
                atomic_dec(&key->user->nkeys);
@@ -1056,7 +1057,7 @@ error:
        return ret;
 
 quota_overrun:
-       spin_unlock(&newowner->lock);
+       spin_unlock_irqrestore(&newowner->lock, flags);
        zapowner = newowner;
        ret = -EDQUOT;
        goto error_put;
index dbfdd8536468da6ae09646bca5068a06c770d777..1fb8aa0019953bed705eca818176a8820d29af39 100644 (file)
@@ -1,3 +1,6 @@
+config HAVE_TRUSTED_KEYS
+       bool
+
 config TRUSTED_KEYS_TPM
        bool "TPM-based trusted keys"
        depends on TCG_TPM >= TRUSTED_KEYS
@@ -9,6 +12,7 @@ config TRUSTED_KEYS_TPM
        select ASN1_ENCODER
        select OID_REGISTRY
        select ASN1
+       select HAVE_TRUSTED_KEYS
        help
          Enable use of the Trusted Platform Module (TPM) as trusted key
          backend. Trusted keys are random number symmetric keys,
@@ -20,6 +24,7 @@ config TRUSTED_KEYS_TEE
        bool "TEE-based trusted keys"
        depends on TEE >= TRUSTED_KEYS
        default y
+       select HAVE_TRUSTED_KEYS
        help
          Enable use of the Trusted Execution Environment (TEE) as trusted
          key backend.
@@ -29,10 +34,19 @@ config TRUSTED_KEYS_CAAM
        depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
        select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
        default y
+       select HAVE_TRUSTED_KEYS
        help
          Enable use of NXP's Cryptographic Accelerator and Assurance Module
          (CAAM) as trusted key backend.
 
-if !TRUSTED_KEYS_TPM && !TRUSTED_KEYS_TEE && !TRUSTED_KEYS_CAAM
-comment "No trust source selected!"
+config TRUSTED_KEYS_DCP
+       bool "DCP-based trusted keys"
+       depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
+       default y
+       select HAVE_TRUSTED_KEYS
+       help
+         Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
+
+if !HAVE_TRUSTED_KEYS
+       comment "No trust source selected!"
 endif
index 735aa0bc08efc2fb799f3b724918485bb00d146c..f0f3b27f688bc82cf8d59e03e4d9f2c92b56775d 100644 (file)
@@ -14,3 +14,5 @@ trusted-$(CONFIG_TRUSTED_KEYS_TPM) += tpm2key.asn1.o
 trusted-$(CONFIG_TRUSTED_KEYS_TEE) += trusted_tee.o
 
 trusted-$(CONFIG_TRUSTED_KEYS_CAAM) += trusted_caam.o
+
+trusted-$(CONFIG_TRUSTED_KEYS_DCP) += trusted_dcp.o
index fee1ab2c734d32b1946785b3e3beb678d492b24b..5113aeae56283c0a66cae019517320d519486652 100644 (file)
@@ -10,6 +10,7 @@
 #include <keys/trusted-type.h>
 #include <keys/trusted_tee.h>
 #include <keys/trusted_caam.h>
+#include <keys/trusted_dcp.h>
 #include <keys/trusted_tpm.h>
 #include <linux/capability.h>
 #include <linux/err.h>
@@ -30,7 +31,7 @@ MODULE_PARM_DESC(rng, "Select trusted key RNG");
 
 static char *trusted_key_source;
 module_param_named(source, trusted_key_source, charp, 0);
-MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee or caam)");
+MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam or dcp)");
 
 static const struct trusted_key_source trusted_key_sources[] = {
 #if defined(CONFIG_TRUSTED_KEYS_TPM)
@@ -42,6 +43,9 @@ static const struct trusted_key_source trusted_key_sources[] = {
 #if defined(CONFIG_TRUSTED_KEYS_CAAM)
        { "caam", &trusted_key_caam_ops },
 #endif
+#if defined(CONFIG_TRUSTED_KEYS_DCP)
+       { "dcp", &dcp_trusted_key_ops },
+#endif
 };
 
 DEFINE_STATIC_CALL_NULL(trusted_key_seal, *trusted_key_sources[0].ops->seal);
diff --git a/security/keys/trusted-keys/trusted_dcp.c b/security/keys/trusted-keys/trusted_dcp.c
new file mode 100644 (file)
index 0000000..b5f81a0
--- /dev/null
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 sigma star gmbh
+ */
+
+#include <crypto/aead.h>
+#include <crypto/aes.h>
+#include <crypto/algapi.h>
+#include <crypto/gcm.h>
+#include <crypto/skcipher.h>
+#include <keys/trusted-type.h>
+#include <linux/key-type.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <soc/fsl/dcp.h>
+
+#define DCP_BLOB_VERSION 1
+#define DCP_BLOB_AUTHLEN 16
+
+/**
+ * DOC: dcp blob format
+ *
+ * The Data Co-Processor (DCP) provides hardware-bound AES keys using its
+ * AES encryption engine only. It does not provide direct key sealing/unsealing.
+ * To make DCP hardware encryption keys usable as trust source, we define
+ * our own custom format that uses a hardware-bound key to secure the sealing
+ * key stored in the key blob.
+ *
+ * Whenever a new trusted key using DCP is generated, we generate a random 128-bit
+ * blob encryption key (BEK) and 128-bit nonce. The BEK and nonce are used to
+ * encrypt the trusted key payload using AES-128-GCM.
+ *
+ * The BEK itself is encrypted using the hardware-bound key using the DCP's AES
+ * encryption engine with AES-128-ECB. The encrypted BEK, generated nonce,
+ * BEK-encrypted payload and authentication tag make up the blob format together
+ * with a version number, payload length and authentication tag.
+ */
+
+/**
+ * struct dcp_blob_fmt - DCP BLOB format.
+ *
+ * @fmt_version: Format version, currently being %1.
+ * @blob_key: Random AES 128 key which is used to encrypt @payload,
+ *            @blob_key itself is encrypted with OTP or UNIQUE device key in
+ *            AES-128-ECB mode by DCP.
+ * @nonce: Random nonce used for @payload encryption.
+ * @payload_len: Length of the plain text @payload.
+ * @payload: The payload itself, encrypted using AES-128-GCM and @blob_key,
+ *           GCM auth tag of size DCP_BLOB_AUTHLEN is attached at the end of it.
+ *
+ * The total size of a DCP BLOB is sizeof(struct dcp_blob_fmt) + @payload_len +
+ * DCP_BLOB_AUTHLEN.
+ */
+struct dcp_blob_fmt {
+       __u8 fmt_version;
+       __u8 blob_key[AES_KEYSIZE_128];
+       __u8 nonce[AES_KEYSIZE_128];
+       __le32 payload_len;
+       __u8 payload[];
+} __packed;
+
+static bool use_otp_key;
+module_param_named(dcp_use_otp_key, use_otp_key, bool, 0);
+MODULE_PARM_DESC(dcp_use_otp_key, "Use OTP instead of UNIQUE key for sealing");
+
+static bool skip_zk_test;
+module_param_named(dcp_skip_zk_test, skip_zk_test, bool, 0);
+MODULE_PARM_DESC(dcp_skip_zk_test, "Don't test whether device keys are zero'ed");
+
+static unsigned int calc_blob_len(unsigned int payload_len)
+{
+       return sizeof(struct dcp_blob_fmt) + payload_len + DCP_BLOB_AUTHLEN;
+}
+
+static int do_dcp_crypto(u8 *in, u8 *out, bool do_encrypt)
+{
+       struct skcipher_request *req = NULL;
+       struct scatterlist src_sg, dst_sg;
+       struct crypto_skcipher *tfm;
+       u8 paes_key[DCP_PAES_KEYSIZE];
+       DECLARE_CRYPTO_WAIT(wait);
+       int res = 0;
+
+       if (use_otp_key)
+               paes_key[0] = DCP_PAES_KEY_OTP;
+       else
+               paes_key[0] = DCP_PAES_KEY_UNIQUE;
+
+       tfm = crypto_alloc_skcipher("ecb-paes-dcp", CRYPTO_ALG_INTERNAL,
+                                   CRYPTO_ALG_INTERNAL);
+       if (IS_ERR(tfm)) {
+               res = PTR_ERR(tfm);
+               tfm = NULL;
+               goto out;
+       }
+
+       req = skcipher_request_alloc(tfm, GFP_NOFS);
+       if (!req) {
+               res = -ENOMEM;
+               goto out;
+       }
+
+       skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
+                                     CRYPTO_TFM_REQ_MAY_SLEEP,
+                                     crypto_req_done, &wait);
+       res = crypto_skcipher_setkey(tfm, paes_key, sizeof(paes_key));
+       if (res < 0)
+               goto out;
+
+       sg_init_one(&src_sg, in, AES_KEYSIZE_128);
+       sg_init_one(&dst_sg, out, AES_KEYSIZE_128);
+       skcipher_request_set_crypt(req, &src_sg, &dst_sg, AES_KEYSIZE_128,
+                                  NULL);
+
+       if (do_encrypt)
+               res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
+       else
+               res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
+
+out:
+       skcipher_request_free(req);
+       crypto_free_skcipher(tfm);
+
+       return res;
+}
+
+static int do_aead_crypto(u8 *in, u8 *out, size_t len, u8 *key, u8 *nonce,
+                         bool do_encrypt)
+{
+       struct aead_request *aead_req = NULL;
+       struct scatterlist src_sg, dst_sg;
+       struct crypto_aead *aead;
+       int ret;
+
+       aead = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
+       if (IS_ERR(aead)) {
+               ret = PTR_ERR(aead);
+               goto out;
+       }
+
+       ret = crypto_aead_setauthsize(aead, DCP_BLOB_AUTHLEN);
+       if (ret < 0) {
+               pr_err("Can't set crypto auth tag len: %d\n", ret);
+               goto free_aead;
+       }
+
+       aead_req = aead_request_alloc(aead, GFP_KERNEL);
+       if (!aead_req) {
+               ret = -ENOMEM;
+               goto free_aead;
+       }
+
+       sg_init_one(&src_sg, in, len);
+       if (do_encrypt) {
+               /*
+                * If we encrypt our buffer has extra space for the auth tag.
+                */
+               sg_init_one(&dst_sg, out, len + DCP_BLOB_AUTHLEN);
+       } else {
+               sg_init_one(&dst_sg, out, len);
+       }
+
+       aead_request_set_crypt(aead_req, &src_sg, &dst_sg, len, nonce);
+       aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL,
+                                 NULL);
+       aead_request_set_ad(aead_req, 0);
+
+       if (crypto_aead_setkey(aead, key, AES_KEYSIZE_128)) {
+               pr_err("Can't set crypto AEAD key\n");
+               ret = -EINVAL;
+               goto free_req;
+       }
+
+       if (do_encrypt)
+               ret = crypto_aead_encrypt(aead_req);
+       else
+               ret = crypto_aead_decrypt(aead_req);
+
+free_req:
+       aead_request_free(aead_req);
+free_aead:
+       crypto_free_aead(aead);
+out:
+       return ret;
+}
+
+static int decrypt_blob_key(u8 *key)
+{
+       return do_dcp_crypto(key, key, false);
+}
+
+static int encrypt_blob_key(u8 *key)
+{
+       return do_dcp_crypto(key, key, true);
+}
+
+static int trusted_dcp_seal(struct trusted_key_payload *p, char *datablob)
+{
+       struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
+       int blen, ret;
+
+       blen = calc_blob_len(p->key_len);
+       if (blen > MAX_BLOB_SIZE)
+               return -E2BIG;
+
+       b->fmt_version = DCP_BLOB_VERSION;
+       get_random_bytes(b->nonce, AES_KEYSIZE_128);
+       get_random_bytes(b->blob_key, AES_KEYSIZE_128);
+
+       ret = do_aead_crypto(p->key, b->payload, p->key_len, b->blob_key,
+                            b->nonce, true);
+       if (ret) {
+               pr_err("Unable to encrypt blob payload: %i\n", ret);
+               return ret;
+       }
+
+       ret = encrypt_blob_key(b->blob_key);
+       if (ret) {
+               pr_err("Unable to encrypt blob key: %i\n", ret);
+               return ret;
+       }
+
+       b->payload_len = get_unaligned_le32(&p->key_len);
+       p->blob_len = blen;
+       return 0;
+}
+
+static int trusted_dcp_unseal(struct trusted_key_payload *p, char *datablob)
+{
+       struct dcp_blob_fmt *b = (struct dcp_blob_fmt *)p->blob;
+       int blen, ret;
+
+       if (b->fmt_version != DCP_BLOB_VERSION) {
+               pr_err("DCP blob has bad version: %i, expected %i\n",
+                      b->fmt_version, DCP_BLOB_VERSION);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       p->key_len = le32_to_cpu(b->payload_len);
+       blen = calc_blob_len(p->key_len);
+       if (blen != p->blob_len) {
+               pr_err("DCP blob has bad length: %i != %i\n", blen,
+                      p->blob_len);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ret = decrypt_blob_key(b->blob_key);
+       if (ret) {
+               pr_err("Unable to decrypt blob key: %i\n", ret);
+               goto out;
+       }
+
+       ret = do_aead_crypto(b->payload, p->key, p->key_len + DCP_BLOB_AUTHLEN,
+                            b->blob_key, b->nonce, false);
+       if (ret) {
+               pr_err("Unwrap of DCP payload failed: %i\n", ret);
+               goto out;
+       }
+
+       ret = 0;
+out:
+       return ret;
+}
+
+static int test_for_zero_key(void)
+{
+       /*
+        * Encrypting a plaintext of all 0x55 bytes will yield
+        * this ciphertext in case the DCP test key is used.
+        */
+       static const u8 bad[] = {0x9a, 0xda, 0xe0, 0x54, 0xf6, 0x3d, 0xfa, 0xff,
+                                0x5e, 0xa1, 0x8e, 0x45, 0xed, 0xf6, 0xea, 0x6f};
+       void *buf = NULL;
+       int ret = 0;
+
+       if (skip_zk_test)
+               goto out;
+
+       buf = kmalloc(AES_BLOCK_SIZE, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memset(buf, 0x55, AES_BLOCK_SIZE);
+
+       ret = do_dcp_crypto(buf, buf, true);
+       if (ret)
+               goto out;
+
+       if (memcmp(buf, bad, AES_BLOCK_SIZE) == 0) {
+               pr_warn("Device neither in secure nor trusted mode!\n");
+               ret = -EINVAL;
+       }
+out:
+       kfree(buf);
+       return ret;
+}
+
+static int trusted_dcp_init(void)
+{
+       int ret;
+
+       if (use_otp_key)
+               pr_info("Using DCP OTP key\n");
+
+       ret = test_for_zero_key();
+       if (ret) {
+               pr_warn("Test for zero'ed keys failed: %i\n", ret);
+
+               return -EINVAL;
+       }
+
+       return register_key_type(&key_type_trusted);
+}
+
+static void trusted_dcp_exit(void)
+{
+       unregister_key_type(&key_type_trusted);
+}
+
+struct trusted_key_ops dcp_trusted_key_ops = {
+       .exit = trusted_dcp_exit,
+       .init = trusted_dcp_init,
+       .seal = trusted_dcp_seal,
+       .unseal = trusted_dcp_unseal,
+       .migratable = 0,
+};
index aa108bea6739b302e9ef4f274f47a05d44014dce..89c9798d18007192f30e6cd21605b78cd6cb55d9 100644 (file)
@@ -356,17 +356,28 @@ out:
  */
 int trusted_tpm_send(unsigned char *cmd, size_t buflen)
 {
+       struct tpm_buf buf;
        int rc;
 
        if (!chip)
                return -ENODEV;
 
+       rc = tpm_try_get_ops(chip);
+       if (rc)
+               return rc;
+
+       buf.flags = 0;
+       buf.length = buflen;
+       buf.data = cmd;
        dump_tpm_buf(cmd);
-       rc = tpm_send(chip, cmd, buflen);
+       rc = tpm_transmit_cmd(chip, &buf, 4, "sending data");
        dump_tpm_buf(cmd);
+
        if (rc > 0)
-               /* Can't return positive return codes values to keyctl */
+               /* TPM error */
                rc = -EPERM;
+
+       tpm_put_ops(chip);
        return rc;
 }
 EXPORT_SYMBOL_GPL(trusted_tpm_send);
@@ -407,7 +418,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s,
        tpm_buf_append_u32(tb, handle);
        tpm_buf_append(tb, ononce, TPM_NONCE_SIZE);
 
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       ret = trusted_tpm_send(tb->data, tb->length);
        if (ret < 0)
                return ret;
 
@@ -431,7 +442,7 @@ int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
                return -ENODEV;
 
        tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       ret = trusted_tpm_send(tb->data, tb->length);
        if (ret < 0)
                return ret;
 
@@ -543,7 +554,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
        tpm_buf_append_u8(tb, cont);
        tpm_buf_append(tb, td->pubauth, SHA1_DIGEST_SIZE);
 
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       ret = trusted_tpm_send(tb->data, tb->length);
        if (ret < 0)
                goto out;
 
@@ -634,7 +645,7 @@ static int tpm_unseal(struct tpm_buf *tb,
        tpm_buf_append_u8(tb, cont);
        tpm_buf_append(tb, authdata2, SHA1_DIGEST_SIZE);
 
-       ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
+       ret = trusted_tpm_send(tb->data, tb->length);
        if (ret < 0) {
                pr_info("authhmac failed (%d)\n", ret);
                return ret;
index bc700f85f80be73e587522aab8df7b81f6f830c1..dfeec06301cea3fe3978b84f619435ed837f7d9e 100644 (file)
@@ -228,8 +228,9 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
                      struct trusted_key_payload *payload,
                      struct trusted_key_options *options)
 {
+       off_t offset = TPM_HEADER_SIZE;
+       struct tpm_buf buf, sized;
        int blob_len = 0;
-       struct tpm_buf buf;
        u32 hash;
        u32 flags;
        int i;
@@ -252,50 +253,58 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
        if (rc)
                return rc;
 
+       rc = tpm2_start_auth_session(chip);
+       if (rc)
+               goto out_put;
+
        rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
        if (rc) {
-               tpm_put_ops(chip);
-               return rc;
+               tpm2_end_auth_session(chip);
+               goto out_put;
        }
 
-       tpm_buf_append_u32(&buf, options->keyhandle);
-       tpm2_buf_append_auth(&buf, TPM2_RS_PW,
-                            NULL /* nonce */, 0,
-                            0 /* session_attributes */,
-                            options->keyauth /* hmac */,
-                            TPM_DIGEST_SIZE);
+       rc = tpm_buf_init_sized(&sized);
+       if (rc) {
+               tpm_buf_destroy(&buf);
+               tpm2_end_auth_session(chip);
+               goto out_put;
+       }
+
+       tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
+       tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_DECRYPT,
+                                   options->keyauth, TPM_DIGEST_SIZE);
 
        /* sensitive */
-       tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len);
+       tpm_buf_append_u16(&sized, options->blobauth_len);
 
-       tpm_buf_append_u16(&buf, options->blobauth_len);
        if (options->blobauth_len)
-               tpm_buf_append(&buf, options->blobauth, options->blobauth_len);
+               tpm_buf_append(&sized, options->blobauth, options->blobauth_len);
 
-       tpm_buf_append_u16(&buf, payload->key_len);
-       tpm_buf_append(&buf, payload->key, payload->key_len);
+       tpm_buf_append_u16(&sized, payload->key_len);
+       tpm_buf_append(&sized, payload->key, payload->key_len);
+       tpm_buf_append(&buf, sized.data, sized.length);
 
        /* public */
-       tpm_buf_append_u16(&buf, 14 + options->policydigest_len);
-       tpm_buf_append_u16(&buf, TPM_ALG_KEYEDHASH);
-       tpm_buf_append_u16(&buf, hash);
+       tpm_buf_reset_sized(&sized);
+       tpm_buf_append_u16(&sized, TPM_ALG_KEYEDHASH);
+       tpm_buf_append_u16(&sized, hash);
 
        /* key properties */
        flags = 0;
        flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH;
-       flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM |
-                                           TPM2_OA_FIXED_PARENT);
-       tpm_buf_append_u32(&buf, flags);
+       flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT);
+       tpm_buf_append_u32(&sized, flags);
 
        /* policy */
-       tpm_buf_append_u16(&buf, options->policydigest_len);
+       tpm_buf_append_u16(&sized, options->policydigest_len);
        if (options->policydigest_len)
-               tpm_buf_append(&buf, options->policydigest,
-                              options->policydigest_len);
+               tpm_buf_append(&sized, options->policydigest, options->policydigest_len);
 
        /* public parameters */
-       tpm_buf_append_u16(&buf, TPM_ALG_NULL);
-       tpm_buf_append_u16(&buf, 0);
+       tpm_buf_append_u16(&sized, TPM_ALG_NULL);
+       tpm_buf_append_u16(&sized, 0);
+
+       tpm_buf_append(&buf, sized.data, sized.length);
 
        /* outside info */
        tpm_buf_append_u16(&buf, 0);
@@ -305,28 +314,30 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 
        if (buf.flags & TPM_BUF_OVERFLOW) {
                rc = -E2BIG;
+               tpm2_end_auth_session(chip);
                goto out;
        }
 
+       tpm_buf_fill_hmac_session(chip, &buf);
        rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
+       rc = tpm_buf_check_hmac_response(chip, &buf, rc);
        if (rc)
                goto out;
 
-       blob_len = be32_to_cpup((__be32 *) &buf.data[TPM_HEADER_SIZE]);
-       if (blob_len > MAX_BLOB_SIZE) {
+       blob_len = tpm_buf_read_u32(&buf, &offset);
+       if (blob_len > MAX_BLOB_SIZE || buf.flags & TPM_BUF_BOUNDARY_ERROR) {
                rc = -E2BIG;
                goto out;
        }
-       if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) {
+       if (buf.length - offset < blob_len) {
                rc = -EFAULT;
                goto out;
        }
 
-       blob_len = tpm2_key_encode(payload, options,
-                                  &buf.data[TPM_HEADER_SIZE + 4],
-                                  blob_len);
+       blob_len = tpm2_key_encode(payload, options, &buf.data[offset], blob_len);
 
 out:
+       tpm_buf_destroy(&sized);
        tpm_buf_destroy(&buf);
 
        if (rc > 0) {
@@ -340,6 +351,7 @@ out:
        else
                payload->blob_len = blob_len;
 
+out_put:
        tpm_put_ops(chip);
        return rc;
 }
@@ -409,25 +421,31 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
        if (blob_len > payload->blob_len)
                return -E2BIG;
 
-       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
+       rc = tpm2_start_auth_session(chip);
        if (rc)
                return rc;
 
-       tpm_buf_append_u32(&buf, options->keyhandle);
-       tpm2_buf_append_auth(&buf, TPM2_RS_PW,
-                            NULL /* nonce */, 0,
-                            0 /* session_attributes */,
-                            options->keyauth /* hmac */,
-                            TPM_DIGEST_SIZE);
+       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
+       if (rc) {
+               tpm2_end_auth_session(chip);
+               return rc;
+       }
+
+       tpm_buf_append_name(chip, &buf, options->keyhandle, NULL);
+       tpm_buf_append_hmac_session(chip, &buf, 0, options->keyauth,
+                                   TPM_DIGEST_SIZE);
 
        tpm_buf_append(&buf, blob, blob_len);
 
        if (buf.flags & TPM_BUF_OVERFLOW) {
                rc = -E2BIG;
+               tpm2_end_auth_session(chip);
                goto out;
        }
 
+       tpm_buf_fill_hmac_session(chip, &buf);
        rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
+       rc = tpm_buf_check_hmac_response(chip, &buf, rc);
        if (!rc)
                *blob_handle = be32_to_cpup(
                        (__be32 *) &buf.data[TPM_HEADER_SIZE]);
@@ -465,20 +483,44 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
        u8 *data;
        int rc;
 
-       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
+       rc = tpm2_start_auth_session(chip);
        if (rc)
                return rc;
 
-       tpm_buf_append_u32(&buf, blob_handle);
-       tpm2_buf_append_auth(&buf,
-                            options->policyhandle ?
-                            options->policyhandle : TPM2_RS_PW,
-                            NULL /* nonce */, 0,
-                            TPM2_SA_CONTINUE_SESSION,
-                            options->blobauth /* hmac */,
-                            options->blobauth_len);
+       rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
+       if (rc) {
+               tpm2_end_auth_session(chip);
+               return rc;
+       }
+
+       tpm_buf_append_name(chip, &buf, blob_handle, NULL);
+
+       if (!options->policyhandle) {
+               tpm_buf_append_hmac_session(chip, &buf, TPM2_SA_ENCRYPT,
+                                           options->blobauth,
+                                           options->blobauth_len);
+       } else {
+               /*
+                * FIXME: The policy session was generated outside the
+                * kernel so we don't known the nonce and thus can't
+                * calculate a HMAC on it.  Therefore, the user can
+                * only really use TPM2_PolicyPassword and we must
+                * send down the plain text password, which could be
+                * intercepted.  We can still encrypt the returned
+                * key, but that's small comfort since the interposer
+                * could repeat our actions with the exfiltrated
+                * password.
+                */
+               tpm2_buf_append_auth(&buf, options->policyhandle,
+                                    NULL /* nonce */, 0, 0,
+                                    options->blobauth, options->blobauth_len);
+               tpm_buf_append_hmac_session_opt(chip, &buf, TPM2_SA_ENCRYPT,
+                                               NULL, 0);
+       }
 
+       tpm_buf_fill_hmac_session(chip, &buf);
        rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
+       rc = tpm_buf_check_hmac_response(chip, &buf, rc);
        if (rc > 0)
                rc = -EPERM;
 
index 6a384b922e4fada5bfed7fa8b7e0f95ea7e3457a..d1f6cdcf1866e4162286b32072f7a21dc93ea94f 100644 (file)
@@ -557,9 +557,32 @@ static const struct config_entry *snd_intel_dsp_find_config
                if (table->codec_hid) {
                        int i;
 
-                       for (i = 0; i < table->codec_hid->num_codecs; i++)
-                               if (acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
+                       for (i = 0; i < table->codec_hid->num_codecs; i++) {
+                               struct nhlt_acpi_table *nhlt;
+                               bool ssp_found = false;
+
+                               if (!acpi_dev_present(table->codec_hid->codecs[i], NULL, -1))
+                                       continue;
+
+                               nhlt = intel_nhlt_init(&pci->dev);
+                               if (!nhlt) {
+                                       dev_warn(&pci->dev, "%s: NHLT table not found, skipped HID %s\n",
+                                                __func__, table->codec_hid->codecs[i]);
+                                       continue;
+                               }
+
+                               if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP) &&
+                                   intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S))
+                                       ssp_found = true;
+
+                               intel_nhlt_free(nhlt);
+
+                               if (ssp_found)
                                        break;
+
+                               dev_warn(&pci->dev, "%s: no valid SSP found for HID %s, skipped\n",
+                                        __func__, table->codec_hid->codecs[i]);
+                       }
                        if (i == table->codec_hid->num_codecs)
                                continue;
                }
index 5f60658c6051c90bf06b42c8d39a53e3dd54c1f1..d7417a40392b2dc02647ff3ffb0802cfada6fa35 100644 (file)
@@ -45,6 +45,8 @@ static bool is_link_enabled(struct fwnode_handle *fw_node, u8 idx)
                                 "intel-quirk-mask",
                                 &quirk_mask);
 
+       fwnode_handle_put(link);
+
        if (quirk_mask & SDW_INTEL_QUIRK_MASK_BUS_DISABLE)
                return false;
 
index fe72e7d7724127418b0b5351e64f6dc0d8b2c831..dadeda7758ceebce94d6205d38b0807b1e6c5587 100644 (file)
@@ -189,8 +189,7 @@ static int snd_emu10k1_suspend(struct device *dev)
 
        emu->suspend = 1;
 
-       cancel_work_sync(&emu->emu1010.firmware_work);
-       cancel_work_sync(&emu->emu1010.clock_work);
+       cancel_work_sync(&emu->emu1010.work);
 
        snd_ac97_suspend(emu->ac97);
 
index de5c41e578e1f4ac3cf085f1c8b20c75a545fce8..8ccc0178360ce8c0a5d70b920d212ca299310fd6 100644 (file)
@@ -732,69 +732,67 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, int dock,
        return snd_emu1010_load_firmware_entry(emu, *fw);
 }
 
-static void emu1010_firmware_work(struct work_struct *work)
+static void snd_emu1010_load_dock_firmware(struct snd_emu10k1 *emu)
 {
-       struct snd_emu10k1 *emu;
-       u32 tmp, tmp2, reg;
+       u32 tmp, tmp2;
        int err;
 
-       emu = container_of(work, struct snd_emu10k1,
-                          emu1010.firmware_work);
-       if (emu->card->shutdown)
+       // The docking events clearly arrive prematurely - while the
+       // Dock's FPGA seems to be successfully programmed, the Dock
+       // fails to initialize subsequently if we don't give it some
+       // time to "warm up" here.
+       msleep(200);
+
+       dev_info(emu->card->dev, "emu1010: Loading Audio Dock Firmware\n");
+       /* Return to Audio Dock programming mode */
+       snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
+                              EMU_HANA_FPGA_CONFIG_AUDIODOCK);
+       err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);
+       if (err < 0)
                return;
-#ifdef CONFIG_PM_SLEEP
-       if (emu->suspend)
+       snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
+
+       snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp);
+       dev_dbg(emu->card->dev, "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp);
+       if ((tmp & 0x1f) != 0x15) {
+               /* FPGA failed to be programmed */
+               dev_err(emu->card->dev,
+                       "emu1010: Loading Audio Dock Firmware failed, reg = 0x%x\n",
+                       tmp);
                return;
-#endif
+       }
+       dev_info(emu->card->dev, "emu1010: Audio Dock Firmware loaded\n");
+
+       snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
+       snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
+       dev_info(emu->card->dev, "Audio Dock ver: %u.%u\n", tmp, tmp2);
+
+       /* Allow DLL to settle, to sync clocking between 1010 and Dock */
+       msleep(10);
+}
+
+static void emu1010_dock_event(struct snd_emu10k1 *emu)
+{
+       u32 reg;
+
        snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
        if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
                /* Audio Dock attached */
-               /* Return to Audio Dock programming mode */
-               dev_info(emu->card->dev,
-                        "emu1010: Loading Audio Dock Firmware\n");
-               snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG,
-                                      EMU_HANA_FPGA_CONFIG_AUDIODOCK);
-               err = snd_emu1010_load_firmware(emu, 1, &emu->dock_fw);
-               if (err < 0)
-                       return;
-               snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
-               snd_emu1010_fpga_read(emu, EMU_HANA_ID, &tmp);
-               dev_info(emu->card->dev,
-                        "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", tmp);
-               if ((tmp & 0x1f) != 0x15) {
-                       /* FPGA failed to be programmed */
-                       dev_info(emu->card->dev,
-                                "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n",
-                                tmp);
-                       return;
-               }
-               dev_info(emu->card->dev,
-                        "emu1010: Audio Dock Firmware loaded\n");
-               snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
-               snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
-               dev_info(emu->card->dev, "Audio Dock ver: %u.%u\n", tmp, tmp2);
-               /* Sync clocking between 1010 and Dock */
-               /* Allow DLL to settle */
-               msleep(10);
+               snd_emu1010_load_dock_firmware(emu);
                /* Unmute all. Default is muted after a firmware load */
                snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
+       } else if (!(reg & EMU_HANA_OPTION_DOCK_ONLINE)) {
+               /* Audio Dock removed */
+               dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");
+               /* The hardware auto-mutes all, so we unmute again */
+               snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
        }
 }
 
-static void emu1010_clock_work(struct work_struct *work)
+static void emu1010_clock_event(struct snd_emu10k1 *emu)
 {
-       struct snd_emu10k1 *emu;
        struct snd_ctl_elem_id id;
 
-       emu = container_of(work, struct snd_emu10k1,
-                          emu1010.clock_work);
-       if (emu->card->shutdown)
-               return;
-#ifdef CONFIG_PM_SLEEP
-       if (emu->suspend)
-               return;
-#endif
-
        spin_lock_irq(&emu->reg_lock);
        // This is the only thing that can actually happen.
        emu->emu1010.clock_source = emu->emu1010.clock_fallback;
@@ -805,21 +803,44 @@ static void emu1010_clock_work(struct work_struct *work)
        snd_ctl_notify(emu->card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
 }
 
-static void emu1010_interrupt(struct snd_emu10k1 *emu)
+static void emu1010_work(struct work_struct *work)
 {
+       struct snd_emu10k1 *emu;
        u32 sts;
 
+       emu = container_of(work, struct snd_emu10k1, emu1010.work);
+       if (emu->card->shutdown)
+               return;
+#ifdef CONFIG_PM_SLEEP
+       if (emu->suspend)
+               return;
+#endif
+
+       snd_emu1010_fpga_lock(emu);
+
        snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &sts);
-       if (sts & EMU_HANA_IRQ_DOCK_LOST) {
-               /* Audio Dock removed */
-               dev_info(emu->card->dev, "emu1010: Audio Dock detached\n");
-               /* The hardware auto-mutes all, so we unmute again */
-               snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
-       } else if (sts & EMU_HANA_IRQ_DOCK) {
-               schedule_work(&emu->emu1010.firmware_work);
-       }
+
+       // The distinction of the IRQ status bits is unreliable,
+       // so we dispatch later based on option card status.
+       if (sts & (EMU_HANA_IRQ_DOCK | EMU_HANA_IRQ_DOCK_LOST))
+               emu1010_dock_event(emu);
+
        if (sts & EMU_HANA_IRQ_WCLK_CHANGED)
-               schedule_work(&emu->emu1010.clock_work);
+               emu1010_clock_event(emu);
+
+       snd_emu1010_fpga_unlock(emu);
+}
+
+static void emu1010_interrupt(struct snd_emu10k1 *emu)
+{
+       // We get an interrupt on each GPIO input pin change, but we
+       // care only about the ones triggered by the dedicated pin.
+       u16 sts = inw(emu->port + A_GPIO);
+       u16 bit = emu->card_capabilities->ca0108_chip ? 0x2000 : 0x8000;
+       if (!(sts & bit))
+               return;
+
+       schedule_work(&emu->emu1010.work);
 }
 
 /*
@@ -841,6 +862,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
         * Proper init follows in snd_emu10k1_init(). */
        outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
 
+       snd_emu1010_fpga_lock(emu);
+
        /* Disable 48Volt power to Audio Dock */
        snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
 
@@ -866,7 +889,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
        err = snd_emu1010_load_firmware(emu, 0, &emu->firmware);
        if (err < 0) {
                dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n");
-               return err;
+               goto fail;
        }
 
        /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
@@ -876,7 +899,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
                dev_info(emu->card->dev,
                         "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n",
                         reg);
-               return -ENODEV;
+               err = -ENODEV;
+               goto fail;
        }
 
        dev_info(emu->card->dev, "emu1010: Hana Firmware loaded\n");
@@ -889,7 +913,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
        snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
        dev_info(emu->card->dev, "emu1010: Card options = 0x%x\n", reg);
        if (reg & EMU_HANA_OPTION_DOCK_OFFLINE)
-               schedule_work(&emu->emu1010.firmware_work);
+               snd_emu1010_load_dock_firmware(emu);
        if (emu->card_capabilities->no_adat) {
                emu->emu1010.optical_in = 0; /* IN_SPDIF */
                emu->emu1010.optical_out = 0; /* OUT_SPDIF */
@@ -936,7 +960,9 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
        // so it is safe to simply enable the outputs.
        snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
 
-       return 0;
+fail:
+       snd_emu1010_fpga_unlock(emu);
+       return err;
 }
 /*
  *  Create the EMU10K1 instance
@@ -958,10 +984,10 @@ static void snd_emu10k1_free(struct snd_card *card)
        }
        if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
                /* Disable 48Volt power to Audio Dock */
-               snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_DOCK_PWR, 0);
        }
-       cancel_work_sync(&emu->emu1010.firmware_work);
-       cancel_work_sync(&emu->emu1010.clock_work);
+       cancel_work_sync(&emu->emu1010.work);
+       mutex_destroy(&emu->emu1010.lock);
        release_firmware(emu->firmware);
        release_firmware(emu->dock_fw);
        snd_util_memhdr_free(emu->memhdr);
@@ -1540,8 +1566,8 @@ int snd_emu10k1_create(struct snd_card *card,
        emu->irq = -1;
        emu->synth = NULL;
        emu->get_synth_voice = NULL;
-       INIT_WORK(&emu->emu1010.firmware_work, emu1010_firmware_work);
-       INIT_WORK(&emu->emu1010.clock_work, emu1010_clock_work);
+       INIT_WORK(&emu->emu1010.work, emu1010_work);
+       mutex_init(&emu->emu1010.lock);
        /* read revision & serial */
        emu->revision = pci->revision;
        pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
index 0a32ea53d8c648a78f44227579a76c5e111eda89..05b98d9b547b2a9ffd063649311887693b1b20de 100644 (file)
@@ -661,7 +661,9 @@ static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
        change = (emu->emu1010.output_source[channel] != val);
        if (change) {
                emu->emu1010.output_source[channel] = val;
+               snd_emu1010_fpga_lock(emu);
                snd_emu1010_output_source_apply(emu, channel, val);
+               snd_emu1010_fpga_unlock(emu);
        }
        return change;
 }
@@ -705,7 +707,9 @@ static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
        change = (emu->emu1010.input_source[channel] != val);
        if (change) {
                emu->emu1010.input_source[channel] = val;
+               snd_emu1010_fpga_lock(emu);
                snd_emu1010_input_source_apply(emu, channel, val);
+               snd_emu1010_fpga_unlock(emu);
        }
        return change;
 }
@@ -774,7 +778,7 @@ static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ct
                cache = cache & ~mask;
        change = (cache != emu->emu1010.adc_pads);
        if (change) {
-               snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_ADC_PADS, cache );
                emu->emu1010.adc_pads = cache;
        }
 
@@ -832,7 +836,7 @@ static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ct
                cache = cache & ~mask;
        change = (cache != emu->emu1010.dac_pads);
        if (change) {
-               snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_DAC_PADS, cache );
                emu->emu1010.dac_pads = cache;
        }
 
@@ -980,6 +984,7 @@ static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol,
        val = ucontrol->value.enumerated.item[0] ;
        if (val >= emu_ci->num)
                return -EINVAL;
+       snd_emu1010_fpga_lock(emu);
        spin_lock_irq(&emu->reg_lock);
        change = (emu->emu1010.clock_source != val);
        if (change) {
@@ -996,6 +1001,7 @@ static int snd_emu1010_clock_source_put(struct snd_kcontrol *kcontrol,
        } else {
                spin_unlock_irq(&emu->reg_lock);
        }
+       snd_emu1010_fpga_unlock(emu);
        return change;
 }
 
@@ -1041,7 +1047,7 @@ static int snd_emu1010_clock_fallback_put(struct snd_kcontrol *kcontrol,
        change = (emu->emu1010.clock_fallback != val);
        if (change) {
                emu->emu1010.clock_fallback = val;
-               snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 1 - val);
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_DEFCLOCK, 1 - val);
        }
        return change;
 }
@@ -1093,7 +1099,7 @@ static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol,
                emu->emu1010.optical_out = val;
                tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
                        (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
-               snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp);
        }
        return change;
 }
@@ -1144,7 +1150,7 @@ static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol,
                emu->emu1010.optical_in = val;
                tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : EMU_HANA_OPTICAL_IN_SPDIF) |
                        (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : EMU_HANA_OPTICAL_OUT_SPDIF);
-               snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
+               snd_emu1010_fpga_write_lock(emu, EMU_HANA_OPTICAL_TYPE, tmp);
        }
        return change;
 }
@@ -2323,7 +2329,9 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
                for (i = 0; i < emu_ri->n_outs; i++)
                        emu->emu1010.output_source[i] =
                                emu1010_map_source(emu_ri, emu_ri->out_dflts[i]);
+               snd_emu1010_fpga_lock(emu);
                snd_emu1010_apply_sources(emu);
+               snd_emu1010_fpga_unlock(emu);
 
                kctl = emu->ctl_clock_source = snd_ctl_new1(&snd_emu1010_clock_source, emu);
                err = snd_ctl_add(card, kctl);
index 2f80fd91017c3994e40017f9a9bb5c22ea21603a..737c28d31b41a39a4ca1ddb335df6b907c8e8a30 100644 (file)
@@ -165,6 +165,8 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
        u32 value2;
 
        if (emu->card_capabilities->emu_model) {
+               snd_emu1010_fpga_lock(emu);
+
                // This represents the S/PDIF lock status on 0404b, which is
                // kinda weird and unhelpful, because monitoring it via IRQ is
                // impractical (one gets an IRQ flood as long as it is desynced).
@@ -197,6 +199,8 @@ static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry,
                        snd_iprintf(buffer, "\nS/PDIF mode: %s%s\n",
                                    value & EMU_HANA_SPDIF_MODE_RX_PRO ? "professional" : "consumer",
                                    value & EMU_HANA_SPDIF_MODE_RX_NOCOPY ? ", no copy" : "");
+
+               snd_emu1010_fpga_unlock(emu);
        } else {
                snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
                snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
@@ -458,6 +462,9 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
        struct snd_emu10k1 *emu = entry->private_data;
        u32 value;
        int i;
+
+       snd_emu1010_fpga_lock(emu);
+
        snd_iprintf(buffer, "EMU1010 Registers:\n\n");
 
        for(i = 0; i < 0x40; i+=1) {
@@ -496,6 +503,8 @@ static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
                        snd_emu_proc_emu1010_link_read(emu, buffer, 0x701);
                }
        }
+
+       snd_emu1010_fpga_unlock(emu);
 }
 
 static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
index 74df2330015f66ef3930d05884092d74e4b100af..f4a1c2d4b0787518634dac52ebae9c41a01f05dc 100644 (file)
@@ -285,24 +285,33 @@ static void snd_emu1010_fpga_write_locked(struct snd_emu10k1 *emu, u32 reg, u32
        outw(value, emu->port + A_GPIO);
        udelay(10);
        outw(value | 0x80 , emu->port + A_GPIO);  /* High bit clocks the value into the fpga. */
+       udelay(10);
 }
 
 void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
 {
-       unsigned long flags;
+       if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
+               return;
+       snd_emu1010_fpga_write_locked(emu, reg, value);
+}
 
-       spin_lock_irqsave(&emu->emu_lock, flags);
+void snd_emu1010_fpga_write_lock(struct snd_emu10k1 *emu, u32 reg, u32 value)
+{
+       snd_emu1010_fpga_lock(emu);
        snd_emu1010_fpga_write_locked(emu, reg, value);
-       spin_unlock_irqrestore(&emu->emu_lock, flags);
+       snd_emu1010_fpga_unlock(emu);
 }
 
-static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *value)
+void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
 {
        // The higest input pin is used as the designated interrupt trigger,
        // so it needs to be masked out.
        // But note that any other input pin change will also cause an IRQ,
        // so using this function often causes an IRQ as a side effect.
        u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
+
+       if (snd_BUG_ON(!mutex_is_locked(&emu->emu1010.lock)))
+               return;
        if (snd_BUG_ON(reg > 0x3f))
                return;
        reg += 0x40; /* 0x40 upwards are registers. */
@@ -313,47 +322,31 @@ static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *
        *value = ((inw(emu->port + A_GPIO) >> 8) & mask);
 }
 
-void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&emu->emu_lock, flags);
-       snd_emu1010_fpga_read_locked(emu, reg, value);
-       spin_unlock_irqrestore(&emu->emu_lock, flags);
-}
-
 /* Each Destination has one and only one Source,
  * but one Source can feed any number of Destinations simultaneously.
  */
 void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
 {
-       unsigned long flags;
-
        if (snd_BUG_ON(dst & ~0x71f))
                return;
        if (snd_BUG_ON(src & ~0x71f))
                return;
-       spin_lock_irqsave(&emu->emu_lock, flags);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCHI, src >> 8);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCLO, src & 0x1f);
-       spin_unlock_irqrestore(&emu->emu_lock, flags);
+       snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
+       snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
+       snd_emu1010_fpga_write(emu, EMU_HANA_SRCHI, src >> 8);
+       snd_emu1010_fpga_write(emu, EMU_HANA_SRCLO, src & 0x1f);
 }
 
 u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)
 {
-       unsigned long flags;
        u32 hi, lo;
 
        if (snd_BUG_ON(dst & ~0x71f))
                return 0;
-       spin_lock_irqsave(&emu->emu_lock, flags);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
-       snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
-       snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCHI, &hi);
-       snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCLO, &lo);
-       spin_unlock_irqrestore(&emu->emu_lock, flags);
+       snd_emu1010_fpga_write(emu, EMU_HANA_DESTHI, dst >> 8);
+       snd_emu1010_fpga_write(emu, EMU_HANA_DESTLO, dst & 0x1f);
+       snd_emu1010_fpga_read(emu, EMU_HANA_SRCHI, &hi);
+       snd_emu1010_fpga_read(emu, EMU_HANA_SRCLO, &lo);
        return (hi << 8) | lo;
 }
 
index 1a3f84599cb584331f9766ca6bd5b00bacaa580d..558c1f38fe971859d809e25d774069e73cc642b1 100644 (file)
@@ -644,6 +644,8 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
                ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
                if (ret)
                        goto err_powered_up;
+
+               regcache_cache_only(cs35l56->base.regmap, false);
        }
 
        /* Disable auto-hibernate so that runtime_pm has control */
@@ -1002,6 +1004,8 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
        if (ret)
                goto err;
 
+       regcache_cache_only(cs35l56->base.regmap, false);
+
        ret = cs35l56_set_patch(&cs35l56->base);
        if (ret)
                goto err;
index 70d80b6af3fe370aa9c6f9fd471676ba9c18da72..b29739bd330b1331848553d1f2854694a1be369a 100644 (file)
@@ -920,6 +920,8 @@ static void alc_pre_init(struct hda_codec *codec)
        ((codec)->core.dev.power.power_state.event == PM_EVENT_RESUME)
 #define is_s4_resume(codec) \
        ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
+#define is_s4_suspend(codec) \
+       ((codec)->core.dev.power.power_state.event == PM_EVENT_FREEZE)
 
 static int alc_init(struct hda_codec *codec)
 {
@@ -7183,6 +7185,46 @@ static void alc245_fixup_hp_spectre_x360_eu0xxx(struct hda_codec *codec,
        alc245_fixup_hp_gpio_led(codec, fix, action);
 }
 
+/*
+ * ALC287 PCM hooks
+ */
+static void alc287_alc1318_playback_pcm_hook(struct hda_pcm_stream *hinfo,
+                                  struct hda_codec *codec,
+                                  struct snd_pcm_substream *substream,
+                                  int action)
+{
+       alc_write_coef_idx(codec, 0x10, 0x8806); /* Change MLK to GPIO3 */
+       switch (action) {
+       case HDA_GEN_PCM_ACT_OPEN:
+               alc_write_coefex_idx(codec, 0x5a, 0x00, 0x954f); /* write gpio3 to high */
+               break;
+       case HDA_GEN_PCM_ACT_CLOSE:
+               alc_write_coefex_idx(codec, 0x5a, 0x00, 0x554f); /* write gpio3 as default value */
+               break;
+       }
+}
+
+static void __maybe_unused alc287_s4_power_gpio3_default(struct hda_codec *codec)
+{
+       if (is_s4_suspend(codec)) {
+               alc_write_coef_idx(codec, 0x10, 0x8806); /* Change MLK to GPIO3 */
+               alc_write_coefex_idx(codec, 0x5a, 0x00, 0x554f); /* write gpio3 as default value */
+       }
+}
+
+static void alc287_fixup_lenovo_thinkpad_with_alc1318(struct hda_codec *codec,
+                              const struct hda_fixup *fix, int action)
+{
+       struct alc_spec *spec = codec->spec;
+
+       if (action != HDA_FIXUP_ACT_PRE_PROBE)
+               return;
+#ifdef CONFIG_PM
+       spec->power_hook = alc287_s4_power_gpio3_default;
+#endif
+       spec->gen.pcm_playback_hook = alc287_alc1318_playback_pcm_hook;
+}
+
 
 enum {
        ALC269_FIXUP_GPIO2,
@@ -7426,6 +7468,7 @@ enum {
        ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
        ALC298_FIXUP_LENOVO_C940_DUET7,
        ALC287_FIXUP_LENOVO_14IRP8_DUETITL,
+       ALC287_FIXUP_LENOVO_LEGION_7,
        ALC287_FIXUP_13S_GEN2_SPEAKERS,
        ALC256_FIXUP_SET_COEF_DEFAULTS,
        ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
@@ -7470,7 +7513,8 @@ enum {
        ALC285_FIXUP_ASUS_GA403U_HEADSET_MIC,
        ALC285_FIXUP_ASUS_GA403U_I2C_SPEAKER2_TO_DAC1,
        ALC285_FIXUP_ASUS_GU605_SPI_2_HEADSET_MIC,
-       ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1
+       ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1,
+       ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -7510,6 +7554,23 @@ static void alc287_fixup_lenovo_14irp8_duetitl(struct hda_codec *codec,
        __snd_hda_apply_fixup(codec, id, action, 0);
 }
 
+/* Another hilarious PCI SSID conflict with Lenovo Legion Pro 7 16ARX8H (with
+ * TAS2781 codec) and Legion 7i 16IAX7 (with CS35L41 codec);
+ * we apply a corresponding fixup depending on the codec SSID instead
+ */
+static void alc287_fixup_lenovo_legion_7(struct hda_codec *codec,
+                                        const struct hda_fixup *fix,
+                                        int action)
+{
+       int id;
+
+       if (codec->core.subsystem_id == 0x17aa38a8)
+               id = ALC287_FIXUP_TAS2781_I2C; /* Legion Pro 7 16ARX8H */
+       else
+               id = ALC287_FIXUP_CS35L41_I2C_2; /* Legion 7i 16IAX7 */
+       __snd_hda_apply_fixup(codec, id, action, 0);
+}
+
 static const struct hda_fixup alc269_fixups[] = {
        [ALC269_FIXUP_GPIO2] = {
                .type = HDA_FIXUP_FUNC,
@@ -9404,6 +9465,10 @@ static const struct hda_fixup alc269_fixups[] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc287_fixup_lenovo_14irp8_duetitl,
        },
+       [ALC287_FIXUP_LENOVO_LEGION_7] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc287_fixup_lenovo_legion_7,
+       },
        [ALC287_FIXUP_13S_GEN2_SPEAKERS] = {
                .type = HDA_FIXUP_VERBS,
                .v.verbs = (const struct hda_verb[]) {
@@ -9726,6 +9791,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC285_FIXUP_ASUS_GA403U,
        },
+       [ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc287_fixup_lenovo_thinkpad_with_alc1318,
+               .chained = true,
+               .chain_id = ALC269_FIXUP_THINKPAD_ACPI
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -9937,6 +10008,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x860f, "HP ZBook 15 G6", ALC285_FIXUP_HP_GPIO_AMP_INIT),
        SND_PCI_QUIRK(0x103c, 0x861f, "HP Elite Dragonfly G1", ALC285_FIXUP_HP_GPIO_AMP_INIT),
        SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED),
+       SND_PCI_QUIRK(0x103c, 0x86c1, "HP Laptop 15-da3001TU", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
        SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO),
        SND_PCI_QUIRK(0x103c, 0x86e7, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
        SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
@@ -10393,6 +10465,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x2318, "Thinkpad Z13 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x2319, "Thinkpad Z16 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x231a, "Thinkpad Z16 Gen2", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
+       SND_PCI_QUIRK(0x17aa, 0x231e, "Thinkpad", ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318),
+       SND_PCI_QUIRK(0x17aa, 0x231f, "Thinkpad", ALC287_FIXUP_LENOVO_THKPAD_WH_ALC1318),
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
@@ -10422,7 +10496,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3853, "Lenovo Yoga 7 15ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
        SND_PCI_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
        SND_PCI_QUIRK(0x17aa, 0x3869, "Lenovo Yoga7 14IAL7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
-       SND_PCI_QUIRK(0x17aa, 0x386f, "Legion 7i 16IAX7", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x386f, "Legion Pro 7/7i", ALC287_FIXUP_LENOVO_LEGION_7),
        SND_PCI_QUIRK(0x17aa, 0x3870, "Lenovo Yoga 7 14ARB7", ALC287_FIXUP_YOGA7_14ARB7_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3877, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x17aa, 0x3878, "Lenovo Legion 7 Slim 16ARHA7", ALC287_FIXUP_CS35L41_I2C_2),
index 69c68d8e7a6b54fc1fcfc3fac3a73d58403071f5..1760b5d42460afe83f3d50dbcdd73daf9455fc12 100644 (file)
@@ -430,6 +430,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "MRID6"),
                }
        },
+       {
+               .driver_data = &acp6x_card,
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "MDC"),
+                       DMI_MATCH(DMI_BOARD_NAME, "Herbag_MDU"),
+               }
+       },
        {
                .driver_data = &acp6x_card,
                .matches = {
index dfb4ce53491bbaa8800b8e7b3e2737a0a1be47bc..f8e57a2fc3e324fcf4cdefde12b3a8db24239af5 100644 (file)
@@ -1094,6 +1094,7 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf
 static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
 {
        struct wm_adsp *dsp;
+       uint32_t dsp1rx5_src;
        int ret;
 
        dsp = &cs35l41->dsp;
@@ -1113,16 +1114,29 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
                return ret;
        }
 
-       ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC,
-                          CS35L41_INPUT_SRC_VPMON);
+       switch (cs35l41->hw_cfg.bst_type) {
+       case CS35L41_INT_BOOST:
+       case CS35L41_SHD_BOOST_ACTV:
+               dsp1rx5_src = CS35L41_INPUT_SRC_VPMON;
+               break;
+       case CS35L41_EXT_BOOST:
+       case CS35L41_SHD_BOOST_PASS:
+               dsp1rx5_src = CS35L41_INPUT_SRC_VBSTMON;
+               break;
+       default:
+               dev_err(cs35l41->dev, "wm_halo_init failed - Invalid Boost Type: %d\n",
+                       cs35l41->hw_cfg.bst_type);
+               goto err_dsp;
+       }
+
+       ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC, dsp1rx5_src);
        if (ret < 0) {
-               dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret);
+               dev_err(cs35l41->dev, "Write DSP1RX5_SRC: %d failed: %d\n", dsp1rx5_src, ret);
                goto err_dsp;
        }
-       ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC,
-                          CS35L41_INPUT_SRC_CLASSH);
+       ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC, CS35L41_INPUT_SRC_VBSTMON);
        if (ret < 0) {
-               dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret);
+               dev_err(cs35l41->dev, "Write CS35L41_INPUT_SRC_VBSTMON failed: %d\n", ret);
                goto err_dsp;
        }
        ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC,
index 14a5f86019aad47390ee8f3962a596296dfbf437..70ff55c1517fe02d2a75e7d683e58edcb01947d0 100644 (file)
@@ -188,8 +188,6 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral)
                        goto out;
        }
 
-       regcache_cache_only(cs35l56->base.regmap, false);
-
        ret = cs35l56_init(cs35l56);
        if (ret < 0) {
                regcache_cache_only(cs35l56->base.regmap, true);
index 08cac58e3ab2223c82b4da10314f04b2f055b5b6..fd02b621da52c0c68420f995764e752b6a789597 100644 (file)
@@ -40,16 +40,11 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);
 static const struct reg_default cs35l56_reg_defaults[] = {
        /* no defaults for OTP_MEM - first read populates cache */
 
-       { CS35L56_ASP1_ENABLES1,                0x00000000 },
-       { CS35L56_ASP1_CONTROL1,                0x00000028 },
-       { CS35L56_ASP1_CONTROL2,                0x18180200 },
-       { CS35L56_ASP1_CONTROL3,                0x00000002 },
-       { CS35L56_ASP1_FRAME_CONTROL1,          0x03020100 },
-       { CS35L56_ASP1_FRAME_CONTROL5,          0x00020100 },
-       { CS35L56_ASP1_DATA_CONTROL1,           0x00000018 },
-       { CS35L56_ASP1_DATA_CONTROL5,           0x00000018 },
-
-       /* no defaults for ASP1TX mixer */
+       /*
+        * No defaults for ASP1 control or ASP1TX mixer. See
+        * cs35l56_populate_asp1_register_defaults() and
+        * cs35l56_sync_asp1_mixer_widgets_with_firmware().
+        */
 
        { CS35L56_SWIRE_DP3_CH1_INPUT,          0x00000018 },
        { CS35L56_SWIRE_DP3_CH2_INPUT,          0x00000019 },
@@ -210,6 +205,36 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
        }
 }
 
+static const struct reg_sequence cs35l56_asp1_defaults[] = {
+       REG_SEQ0(CS35L56_ASP1_ENABLES1,         0x00000000),
+       REG_SEQ0(CS35L56_ASP1_CONTROL1,         0x00000028),
+       REG_SEQ0(CS35L56_ASP1_CONTROL2,         0x18180200),
+       REG_SEQ0(CS35L56_ASP1_CONTROL3,         0x00000002),
+       REG_SEQ0(CS35L56_ASP1_FRAME_CONTROL1,   0x03020100),
+       REG_SEQ0(CS35L56_ASP1_FRAME_CONTROL5,   0x00020100),
+       REG_SEQ0(CS35L56_ASP1_DATA_CONTROL1,    0x00000018),
+       REG_SEQ0(CS35L56_ASP1_DATA_CONTROL5,    0x00000018),
+};
+
+/*
+ * The firmware can have control of the ASP so we don't provide regmap
+ * with defaults for these registers, to prevent a regcache_sync() from
+ * overwriting the firmware settings. But if the machine driver hooks up
+ * the ASP it means the driver is taking control of the ASP, so then the
+ * registers are populated with the defaults.
+ */
+int cs35l56_init_asp1_regs_for_driver_control(struct cs35l56_base *cs35l56_base)
+{
+       if (!cs35l56_base->fw_owns_asp1)
+               return 0;
+
+       cs35l56_base->fw_owns_asp1 = false;
+
+       return regmap_multi_reg_write(cs35l56_base->regmap, cs35l56_asp1_defaults,
+                                     ARRAY_SIZE(cs35l56_asp1_defaults));
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_init_asp1_regs_for_driver_control, SND_SOC_CS35L56_SHARED);
+
 /*
  * The firmware boot sequence can overwrite the ASP1 config registers so that
  * they don't match regmap's view of their values. Rewrite the values from the
@@ -217,19 +242,15 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
  */
 int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base)
 {
-       struct reg_sequence asp1_regs[] = {
-               { .reg = CS35L56_ASP1_ENABLES1 },
-               { .reg = CS35L56_ASP1_CONTROL1 },
-               { .reg = CS35L56_ASP1_CONTROL2 },
-               { .reg = CS35L56_ASP1_CONTROL3 },
-               { .reg = CS35L56_ASP1_FRAME_CONTROL1 },
-               { .reg = CS35L56_ASP1_FRAME_CONTROL5 },
-               { .reg = CS35L56_ASP1_DATA_CONTROL1 },
-               { .reg = CS35L56_ASP1_DATA_CONTROL5 },
-       };
+       struct reg_sequence asp1_regs[ARRAY_SIZE(cs35l56_asp1_defaults)];
        int i, ret;
 
-       /* Read values from regmap cache into a write sequence */
+       if (cs35l56_base->fw_owns_asp1)
+               return 0;
+
+       memcpy(asp1_regs, cs35l56_asp1_defaults, sizeof(asp1_regs));
+
+       /* Read current values from regmap cache into the write sequence */
        for (i = 0; i < ARRAY_SIZE(asp1_regs); ++i) {
                ret = regmap_read(cs35l56_base->regmap, asp1_regs[i].reg, &asp1_regs[i].def);
                if (ret)
@@ -307,10 +328,10 @@ int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
                reg = CS35L56_DSP1_HALO_STATE;
 
        /*
-        * This can't be a regmap_read_poll_timeout() because cs35l56 will NAK
-        * I2C until it has booted which would terminate the poll
+        * The regmap must remain in cache-only until the chip has
+        * booted, so use a bypassed read of the status register.
         */
-       poll_ret = read_poll_timeout(regmap_read, read_ret,
+       poll_ret = read_poll_timeout(regmap_read_bypassed, read_ret,
                                     (val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
                                     CS35L56_HALO_STATE_POLL_US,
                                     CS35L56_HALO_STATE_TIMEOUT_US,
@@ -362,7 +383,8 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
                return;
 
        cs35l56_wait_control_port_ready();
-       regcache_cache_only(cs35l56_base->regmap, false);
+
+       /* Leave in cache-only. This will be revoked when the chip has rebooted. */
 }
 EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND_SOC_CS35L56_SHARED);
 
@@ -577,14 +599,14 @@ int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_sou
                cs35l56_issue_wake_event(cs35l56_base);
 
 out_sync:
-       regcache_cache_only(cs35l56_base->regmap, false);
-
        ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
        if (ret) {
                dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
                goto err;
        }
 
+       regcache_cache_only(cs35l56_base->regmap, false);
+
        ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
        if (ret)
                goto err;
@@ -684,7 +706,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, SND_SOC_CS35L56_SHARED);
 
 int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base)
 {
-       u64 silicon_uid;
+       u64 silicon_uid = 0;
        int ret;
 
        /* Driver can't apply calibration to a secured part, so skip */
@@ -757,7 +779,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
         * devices so the REVID needs to be determined before waiting for the
         * firmware to boot.
         */
-       ret = regmap_read(cs35l56_base->regmap, CS35L56_REVID, &revid);
+       ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_REVID, &revid);
        if (ret < 0) {
                dev_err(cs35l56_base->dev, "Get Revision ID failed\n");
                return ret;
@@ -768,7 +790,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
        if (ret)
                return ret;
 
-       ret = regmap_read(cs35l56_base->regmap, CS35L56_DEVID, &devid);
+       ret = regmap_read_bypassed(cs35l56_base->regmap, CS35L56_DEVID, &devid);
        if (ret < 0) {
                dev_err(cs35l56_base->dev, "Get Device ID failed\n");
                return ret;
@@ -787,6 +809,9 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
 
        cs35l56_base->type = devid & 0xFF;
 
+       /* Silicon is now identified and booted so exit cache-only */
+       regcache_cache_only(cs35l56_base->regmap, false);
+
        ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
        if (ret) {
                dev_err(cs35l56_base->dev, "Get Secure status failed\n");
index 8d2f021fb362812a73d07d10565a23d2b77f6a38..4986e78105daf9ca949815835c94321ad19dfb68 100644 (file)
@@ -454,9 +454,14 @@ static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int f
 {
        struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component);
        unsigned int val;
+       int ret;
 
        dev_dbg(cs35l56->base.dev, "%s: %#x\n", __func__, fmt);
 
+       ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+       if (ret)
+               return ret;
+
        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
        case SND_SOC_DAIFMT_CBC_CFC:
                break;
@@ -530,6 +535,11 @@ static int cs35l56_asp_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx
                                        unsigned int rx_mask, int slots, int slot_width)
 {
        struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
+       int ret;
+
+       ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+       if (ret)
+               return ret;
 
        if ((slots == 0) || (slot_width == 0)) {
                dev_dbg(cs35l56->base.dev, "tdm config cleared\n");
@@ -578,6 +588,11 @@ static int cs35l56_asp_dai_hw_params(struct snd_pcm_substream *substream,
        struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
        unsigned int rate = params_rate(params);
        u8 asp_width, asp_wl;
+       int ret;
+
+       ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+       if (ret)
+               return ret;
 
        asp_wl = params_width(params);
        if (cs35l56->asp_slot_width)
@@ -634,7 +649,11 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai,
                                      int clk_id, unsigned int freq, int dir)
 {
        struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component);
-       int freq_id;
+       int freq_id, ret;
+
+       ret = cs35l56_init_asp1_regs_for_driver_control(&cs35l56->base);
+       if (ret)
+               return ret;
 
        if (freq == 0) {
                cs35l56->sysclk_set = false;
@@ -1341,6 +1360,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
                                    "spk-id-gpios", ACPI_TYPE_PACKAGE, &obj);
        if (ret) {
                dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret);
+               fwnode_handle_put(af01_fwnode);
                return -ENOENT;
        }
 
@@ -1348,6 +1368,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
        if (obj->package.count != 4) {
                dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n",
                         obj->package.count);
+               fwnode_handle_put(af01_fwnode);
                return -ENOENT;
        }
 
@@ -1362,6 +1383,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
                 */
                ret = acpi_dev_add_driver_gpios(adev, cs35l56_af01_spkid_gpios_mapping);
                if (ret) {
+                       fwnode_handle_put(af01_fwnode);
                        return dev_err_probe(cs35l56->base.dev, ret,
                                             "Failed to add gpio mapping to AF01\n");
                }
@@ -1369,14 +1391,17 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
                ret = devm_add_action_or_reset(cs35l56->base.dev,
                                               cs35l56_acpi_dev_release_driver_gpios,
                                               adev);
-               if (ret)
+               if (ret) {
+                       fwnode_handle_put(af01_fwnode);
                        return ret;
+               }
 
                dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n");
        }
 
        desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL);
        if (IS_ERR(desc)) {
+               fwnode_handle_put(af01_fwnode);
                ret = PTR_ERR(desc);
                return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n");
        }
@@ -1385,9 +1410,12 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
        gpiod_put(desc);
 
        if (ret < 0) {
+               fwnode_handle_put(af01_fwnode);
                dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n");
                return ret;
-               }
+       }
+
+       fwnode_handle_put(af01_fwnode);
 
        dev_info(cs35l56->base.dev, "Got spk-id from AF01\n");
 
@@ -1403,6 +1431,9 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
        cs35l56->base.cal_index = -1;
        cs35l56->speaker_id = -ENOENT;
 
+       /* Assume that the firmware owns ASP1 until we know different */
+       cs35l56->base.fw_owns_asp1 = true;
+
        dev_set_drvdata(cs35l56->base.dev, cs35l56);
 
        cs35l56_fill_supply_names(cs35l56->supplies);
@@ -1531,6 +1562,8 @@ post_soft_reset:
                        return ret;
 
                dev_dbg(cs35l56->base.dev, "Firmware rebooted after soft reset\n");
+
+               regcache_cache_only(cs35l56->base.regmap, false);
        }
 
        /* Disable auto-hibernate so that runtime_pm has control */
index 6bc068cdcbe2a89e1488530bfa4e6e9c49c0651c..15e5e3eb592b3008fb47ea4372fed71a08375f01 100644 (file)
@@ -671,8 +671,10 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
                return NULL;
 
        aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
-       if (!aad_pdata)
+       if (!aad_pdata) {
+               fwnode_handle_put(aad_np);
                return NULL;
+       }
 
        aad_pdata->irq = i2c->irq;
 
@@ -753,6 +755,8 @@ static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
        else
                aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
 
+       fwnode_handle_put(aad_np);
+
        return aad_pdata;
 }
 
index e3ba04484813a21904727a09725c608bf27c34a2..d0d24a53df7462cfe88d5d2457078fc1f144f22b 100644 (file)
@@ -444,6 +444,7 @@ struct rt5645_priv {
        struct regmap *regmap;
        struct i2c_client *i2c;
        struct gpio_desc *gpiod_hp_det;
+       struct gpio_desc *gpiod_cbj_sleeve;
        struct snd_soc_jack *hp_jack;
        struct snd_soc_jack *mic_jack;
        struct snd_soc_jack *btn_jack;
@@ -3186,6 +3187,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
                        RT5645_CBJ_MN_JD, 0);
 
+               if (rt5645->gpiod_cbj_sleeve)
+                       gpiod_set_value(rt5645->gpiod_cbj_sleeve, 1);
+
                msleep(600);
                regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
                val &= 0x7;
@@ -3202,6 +3206,8 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                        snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
                        snd_soc_dapm_sync(dapm);
                        rt5645->jack_type = SND_JACK_HEADPHONE;
+                       if (rt5645->gpiod_cbj_sleeve)
+                               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
                }
                if (rt5645->pdata.level_trigger_irq)
                        regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
@@ -3229,6 +3235,9 @@ static int rt5645_jack_detect(struct snd_soc_component *component, int jack_inse
                if (rt5645->pdata.level_trigger_irq)
                        regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
                                RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
+
+               if (rt5645->gpiod_cbj_sleeve)
+                       gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
        }
 
        return rt5645->jack_type;
@@ -4012,6 +4021,16 @@ static int rt5645_i2c_probe(struct i2c_client *i2c)
                        return ret;
        }
 
+       rt5645->gpiod_cbj_sleeve = devm_gpiod_get_optional(&i2c->dev, "cbj-sleeve",
+                                                          GPIOD_OUT_LOW);
+
+       if (IS_ERR(rt5645->gpiod_cbj_sleeve)) {
+               ret = PTR_ERR(rt5645->gpiod_cbj_sleeve);
+               dev_info(&i2c->dev, "failed to initialize gpiod, ret=%d\n", ret);
+               if (ret != -ENOENT)
+                       return ret;
+       }
+
        for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
                rt5645->supplies[i].supply = rt5645_supply_names[i];
 
@@ -4259,6 +4278,9 @@ static void rt5645_i2c_remove(struct i2c_client *i2c)
        cancel_delayed_work_sync(&rt5645->jack_detect_work);
        cancel_delayed_work_sync(&rt5645->rcclock_work);
 
+       if (rt5645->gpiod_cbj_sleeve)
+               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
+
        regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
 }
 
@@ -4274,6 +4296,9 @@ static void rt5645_i2c_shutdown(struct i2c_client *i2c)
                0);
        msleep(20);
        regmap_write(rt5645->regmap, RT5645_RESET, 0);
+
+       if (rt5645->gpiod_cbj_sleeve)
+               gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
 }
 
 static int __maybe_unused rt5645_sys_suspend(struct device *dev)
index 3fb7b9adb61de628705d784fbe64e259bf031089..bc3579203c7a4770cb657b22965a12bc2becefe8 100644 (file)
@@ -316,7 +316,7 @@ static int rt715_sdca_set_amp_gain_8ch_get(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -17625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
 static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
 
 static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol,
@@ -477,7 +477,7 @@ static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {
                        RT715_SDCA_FU_VOL_CTRL, CH_01),
                SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
                        RT715_SDCA_FU_VOL_CTRL, CH_02),
-                       0x2f, 0x7f, 0,
+                       0x2f, 0x3f, 0,
                rt715_sdca_set_amp_gain_get, rt715_sdca_set_amp_gain_put,
                in_vol_tlv),
        RT715_SDCA_EXT_TLV("FU02 Capture Volume",
@@ -485,13 +485,13 @@ static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {
                        RT715_SDCA_FU_VOL_CTRL, CH_01),
                rt715_sdca_set_amp_gain_4ch_get,
                rt715_sdca_set_amp_gain_4ch_put,
-               in_vol_tlv, 4, 0x7f),
+               in_vol_tlv, 4, 0x3f),
        RT715_SDCA_EXT_TLV("FU06 Capture Volume",
                SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
                        RT715_SDCA_FU_VOL_CTRL, CH_01),
                rt715_sdca_set_amp_gain_4ch_get,
                rt715_sdca_set_amp_gain_4ch_put,
-               in_vol_tlv, 4, 0x7f),
+               in_vol_tlv, 4, 0x3f),
        /* MIC Boost Control */
        RT715_SDCA_BOOST_EXT_TLV("FU0E Boost",
                SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
index 7e13868ff99f03110c165dcd706cff46a8eeba5d..f012fe0ded6d2871217f5fa02c49ee0158ad5101 100644 (file)
@@ -111,6 +111,7 @@ static bool rt715_readable_register(struct device *dev, unsigned int reg)
        case 0x839d:
        case 0x83a7:
        case 0x83a9:
+       case 0x752001:
        case 0x752039:
                return true;
        default:
index e0ea3a23f7cc6844691338ff8daae7f2843d2c6e..e5bd9ef812de13378801d82356b54ee4144f219a 100644 (file)
@@ -1330,7 +1330,7 @@ static struct snd_soc_dai_driver rt722_sdca_dai[] = {
                .capture = {
                        .stream_name = "DP6 DMic Capture",
                        .channels_min = 1,
-                       .channels_max = 2,
+                       .channels_max = 4,
                        .rates = RT722_STEREO_RATES,
                        .formats = RT722_FORMATS,
                },
@@ -1439,9 +1439,12 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
        int loop_check, chk_cnt = 100, ret;
        unsigned int calib_status = 0;
 
-       /* Read eFuse */
-       rt722_sdca_index_write(rt722, RT722_VENDOR_SPK_EFUSE, RT722_DC_CALIB_CTRL,
-               0x4808);
+       /* Config analog bias */
+       rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_ANALOG_BIAS_CTL3,
+               0xa081);
+       /* GE related settings */
+       rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_GE_RELATED_CTL2,
+               0xa009);
        /* Button A, B, C, D bypass mode */
        rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_UMP_HID_CTL4,
                0xcf00);
@@ -1475,9 +1478,6 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
                if ((calib_status & 0x0040) == 0x0)
                        break;
        }
-       /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */
-       rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_DIGITAL_MISC_CTRL4,
-               0x0010);
        /* Set ADC09 power entity floating control */
        rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ADC0A_08_PDE_FLOAT_CTL,
                0x2a12);
@@ -1490,8 +1490,21 @@ static void rt722_sdca_jack_preset(struct rt722_sdca_priv *rt722)
        /* Set DAC03 and HP power entity floating control */
        rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_DAC03_HP_PDE_FLOAT_CTL,
                0x4040);
+       rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_ENT_FLOAT_CTRL_1,
+               0x4141);
+       rt722_sdca_index_write(rt722, RT722_VENDOR_HDA_CTL, RT722_FLOAT_CTRL_1,
+               0x0101);
        /* Fine tune PDE40 latency */
        regmap_write(rt722->regmap, 0x2f58, 0x07);
+       regmap_write(rt722->regmap, 0x2f03, 0x06);
+       /* MIC VRefo */
+       rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,
+               RT722_COMBO_JACK_AUTO_CTL1, 0x0200, 0x0200);
+       rt722_sdca_index_update_bits(rt722, RT722_VENDOR_REG,
+               RT722_VREFO_GAT, 0x4000, 0x4000);
+       /* Release HP-JD, EN_CBJ_TIE_GL/R open, en_osw gating auto done bit */
+       rt722_sdca_index_write(rt722, RT722_VENDOR_REG, RT722_DIGITAL_MISC_CTRL4,
+               0x0010);
 }
 
 int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave)
index 44af8901352eb6817e9a6dddd76fc7325a3660ba..2464361a7958c6904d1eca01fb148166a4743eff 100644 (file)
@@ -69,6 +69,7 @@ struct rt722_sdca_dmic_kctrl_priv {
 #define RT722_COMBO_JACK_AUTO_CTL2             0x46
 #define RT722_COMBO_JACK_AUTO_CTL3             0x47
 #define RT722_DIGITAL_MISC_CTRL4               0x4a
+#define RT722_VREFO_GAT                                0x63
 #define RT722_FSM_CTL                          0x67
 #define RT722_SDCA_INTR_REC                    0x82
 #define RT722_SW_CONFIG1                       0x8a
@@ -127,6 +128,8 @@ struct rt722_sdca_dmic_kctrl_priv {
 #define RT722_UMP_HID_CTL6                     0x66
 #define RT722_UMP_HID_CTL7                     0x67
 #define RT722_UMP_HID_CTL8                     0x68
+#define RT722_FLOAT_CTRL_1                     0x70
+#define RT722_ENT_FLOAT_CTRL_1         0x76
 
 /* Parameter & Verb control 01 (0x1a)(NID:20h) */
 #define RT722_HIDDEN_REG_SW_RESET (0x1 << 14)
index 3c025dabaf7a47f180b6f5bdaf6d6f67d128956d..1253695bebd863cab4accfef0616250fb3006830 100644 (file)
@@ -1155,6 +1155,7 @@ static int wsa881x_probe(struct sdw_slave *pdev,
        pdev->prop.sink_ports = GENMASK(WSA881X_MAX_SWR_PORTS, 0);
        pdev->prop.sink_dpn_prop = wsa_sink_dpn_prop;
        pdev->prop.scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
+       pdev->prop.clk_stop_mode1 = true;
        gpiod_direction_output(wsa881x->sd_n, !wsa881x->sd_n_val);
 
        wsa881x->regmap = devm_regmap_init_sdw(pdev, &wsa881x_regmap_config);
index 9d9921e1cd4dedcb2ff4f8e9b59a3b4560d7fa4c..d2554c8577326b533764862829e84b8e001f7016 100644 (file)
@@ -64,7 +64,7 @@ struct avs_icl_memwnd2_desc {
 struct avs_icl_memwnd2 {
        union {
                struct avs_icl_memwnd2_desc slot_desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
-               u8 rsvd[PAGE_SIZE];
+               u8 rsvd[SZ_4K];
        };
        u8 slot_array[AVS_ICL_MEMWND2_SLOTS_COUNT][PAGE_SIZE];
 } __packed;
index 13061bd1488bb4dd506b14aed5c87967bc19aee6..42b42903ae9de7919c6620a5bfba2ef3b54ffb2c 100644 (file)
@@ -1582,6 +1582,8 @@ static int avs_widget_load(struct snd_soc_component *comp, int index,
        if (!le32_to_cpu(dw->priv.size))
                return 0;
 
+       w->no_wname_in_kcontrol_name = true;
+
        if (w->ignore_suspend && !AVS_S0IX_SUPPORTED) {
                dev_info_once(comp->dev, "Device does not support S0IX, check BIOS settings\n");
                w->ignore_suspend = false;
index 05f38d1f7d824dc0f46c5262e0f6616dce1b7411..b41a1147f1c3455de581c729efc72517b35bc6c7 100644 (file)
@@ -636,28 +636,30 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
                                        BYT_RT5640_USE_AMCR0F28),
        },
        {
+               /* Asus T100TAF, unlike other T100TA* models this one has a mono speaker */
                .matches = {
                        DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
                },
                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
                                        BYT_RT5640_JD_SRC_JD2_IN4N |
                                        BYT_RT5640_OVCD_TH_2000UA |
                                        BYT_RT5640_OVCD_SF_0P75 |
+                                       BYT_RT5640_MONO_SPEAKER |
+                                       BYT_RT5640_DIFF_MIC |
+                                       BYT_RT5640_SSP0_AIF2 |
                                        BYT_RT5640_MCLK_EN),
        },
        {
+               /* Asus T100TA and T100TAM, must come after T100TAF (mono spk) match */
                .matches = {
-                       DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
                },
                .driver_data = (void *)(BYT_RT5640_IN1_MAP |
                                        BYT_RT5640_JD_SRC_JD2_IN4N |
                                        BYT_RT5640_OVCD_TH_2000UA |
                                        BYT_RT5640_OVCD_SF_0P75 |
-                                       BYT_RT5640_MONO_SPEAKER |
-                                       BYT_RT5640_DIFF_MIC |
-                                       BYT_RT5640_SSP0_AIF2 |
                                        BYT_RT5640_MCLK_EN),
        },
        {
index b93ea33739f29ddd9b987d7896e9fa2f37c58ccf..6458d5dc4902f665211bb9e4ae7d274e4bff2fdc 100644 (file)
@@ -99,6 +99,7 @@ config SND_MESON_AXG_PDM
 
 config SND_MESON_CARD_UTILS
        tristate
+       select SND_DYNAMIC_MINORS
 
 config SND_MESON_CODEC_GLUE
        tristate
index 3180aa4d3a157e2718b7b3b4bf34a239a68f33e1..8c5605c1e34e8a1bf29e4256ba9625b94205c762 100644 (file)
@@ -318,6 +318,7 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
 
        dai_link->cpus = cpu;
        dai_link->num_cpus = 1;
+       dai_link->nonatomic = true;
 
        ret = meson_card_parse_dai(card, np, dai_link->cpus);
        if (ret)
index bebee0ca8e3889a920a486b01c1a8730eb1988d4..ecb3eb7a9723ddf60e565b95e46b7f31ce1544cb 100644 (file)
@@ -204,18 +204,26 @@ static irqreturn_t axg_fifo_pcm_irq_block(int irq, void *dev_id)
        unsigned int status;
 
        regmap_read(fifo->map, FIFO_STATUS1, &status);
-
        status = FIELD_GET(STATUS1_INT_STS, status);
+       axg_fifo_ack_irq(fifo, status);
+
+       /* Use the thread to call period elapsed on nonatomic links */
        if (status & FIFO_INT_COUNT_REPEAT)
-               snd_pcm_period_elapsed(ss);
-       else
-               dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
-                       status);
+               return IRQ_WAKE_THREAD;
 
-       /* Ack irqs */
-       axg_fifo_ack_irq(fifo, status);
+       dev_dbg(axg_fifo_dev(ss), "unexpected irq - STS 0x%02x\n",
+               status);
+
+       return IRQ_NONE;
+}
+
+static irqreturn_t axg_fifo_pcm_irq_block_thread(int irq, void *dev_id)
+{
+       struct snd_pcm_substream *ss = dev_id;
+
+       snd_pcm_period_elapsed(ss);
 
-       return IRQ_RETVAL(status);
+       return IRQ_HANDLED;
 }
 
 int axg_fifo_pcm_open(struct snd_soc_component *component,
@@ -243,8 +251,9 @@ int axg_fifo_pcm_open(struct snd_soc_component *component,
        if (ret)
                return ret;
 
-       ret = request_irq(fifo->irq, axg_fifo_pcm_irq_block, 0,
-                         dev_name(dev), ss);
+       ret = request_threaded_irq(fifo->irq, axg_fifo_pcm_irq_block,
+                                  axg_fifo_pcm_irq_block_thread,
+                                  IRQF_ONESHOT, dev_name(dev), ss);
        if (ret)
                return ret;
 
index 63333a2b0a9c363d6882d3fe50ecff78da390316..a6579efd37750db01add3c491bb7a8443a76dde7 100644 (file)
@@ -392,6 +392,46 @@ void axg_tdm_stream_free(struct axg_tdm_stream *ts)
 }
 EXPORT_SYMBOL_GPL(axg_tdm_stream_free);
 
+int axg_tdm_stream_set_cont_clocks(struct axg_tdm_stream *ts,
+                                  unsigned int fmt)
+{
+       int ret = 0;
+
+       if (fmt & SND_SOC_DAIFMT_CONT) {
+               /* Clock are already enabled - skipping */
+               if (ts->clk_enabled)
+                       return 0;
+
+               ret = clk_prepare_enable(ts->iface->mclk);
+               if (ret)
+                       return ret;
+
+               ret = clk_prepare_enable(ts->iface->sclk);
+               if (ret)
+                       goto err_sclk;
+
+               ret = clk_prepare_enable(ts->iface->lrclk);
+               if (ret)
+                       goto err_lrclk;
+
+               ts->clk_enabled = true;
+               return 0;
+       }
+
+       /* Clocks are already disabled - skipping */
+       if (!ts->clk_enabled)
+               return 0;
+
+       clk_disable_unprepare(ts->iface->lrclk);
+err_lrclk:
+       clk_disable_unprepare(ts->iface->sclk);
+err_sclk:
+       clk_disable_unprepare(ts->iface->mclk);
+       ts->clk_enabled = false;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(axg_tdm_stream_set_cont_clocks);
+
 MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver");
 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
 MODULE_LICENSE("GPL v2");
index bf708717635bf6531195a1039aee41c3166d8154..62057c71f742e68e4555428281157ebb265b1cc2 100644 (file)
@@ -309,6 +309,7 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream,
                                   struct snd_soc_dai *dai)
 {
        struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai);
+       struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
        int ret;
 
        switch (iface->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -346,7 +347,11 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream,
                        return ret;
        }
 
-       return 0;
+       ret = axg_tdm_stream_set_cont_clocks(ts, iface->fmt);
+       if (ret)
+               dev_err(dai->dev, "failed to apply continuous clock setting\n");
+
+       return ret;
 }
 
 static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream,
@@ -354,19 +359,32 @@ static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream,
 {
        struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
 
-       /* Stop all attached formatters */
-       axg_tdm_stream_stop(ts);
-
-       return 0;
+       return axg_tdm_stream_set_cont_clocks(ts, 0);
 }
 
-static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream,
+static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream,
+                                int cmd,
                                 struct snd_soc_dai *dai)
 {
-       struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
+       struct axg_tdm_stream *ts =
+               snd_soc_dai_get_dma_data(dai, substream);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               axg_tdm_stream_start(ts);
+               break;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+       case SNDRV_PCM_TRIGGER_STOP:
+               axg_tdm_stream_stop(ts);
+               break;
+       default:
+               return -EINVAL;
+       }
 
-       /* Force all attached formatters to update */
-       return axg_tdm_stream_reset(ts);
+       return 0;
 }
 
 static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai)
@@ -412,8 +430,8 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = {
        .set_fmt        = axg_tdm_iface_set_fmt,
        .startup        = axg_tdm_iface_startup,
        .hw_params      = axg_tdm_iface_hw_params,
-       .prepare        = axg_tdm_iface_prepare,
        .hw_free        = axg_tdm_iface_hw_free,
+       .trigger        = axg_tdm_iface_trigger,
 };
 
 /* TDM Backend DAIs */
index 42f7470b9a7f41fd948948c54d58ea30c49831be..daaca10fec9e2bff82164ccccea75f1aefadaba1 100644 (file)
@@ -58,12 +58,17 @@ struct axg_tdm_stream {
        unsigned int physical_width;
        u32 *mask;
        bool ready;
+
+       /* For continuous clock tracking */
+       bool clk_enabled;
 };
 
 struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface);
 void axg_tdm_stream_free(struct axg_tdm_stream *ts);
 int axg_tdm_stream_start(struct axg_tdm_stream *ts);
 void axg_tdm_stream_stop(struct axg_tdm_stream *ts);
+int axg_tdm_stream_set_cont_clocks(struct axg_tdm_stream *ts,
+                                  unsigned int fmt);
 
 static inline int axg_tdm_stream_reset(struct axg_tdm_stream *ts)
 {
index cc84d4c81be9d363d701b1d5c658e26a62079435..238bda5f6b76fa48b186514398840af05644f279 100644 (file)
@@ -350,7 +350,9 @@ static int sof_init_environment(struct snd_sof_dev *sdev)
        }
 
        ret = sof_select_ipc_and_paths(sdev);
-       if (!ret && plat_data->ipc_type != base_profile->ipc_type) {
+       if (ret) {
+               goto err_machine_check;
+       } else if (plat_data->ipc_type != base_profile->ipc_type) {
                /* IPC type changed, re-initialize the ops */
                sof_ops_free(sdev);
 
index 7c8aafca8fdef8eb65211dcd8cbead13077a6068..7275437ea8d8a59433e4aab0429acb4ce66cdf4a 100644 (file)
@@ -330,14 +330,32 @@ EXPORT_SYMBOL_GPL(snd_sof_dbg_memory_info_init);
 
 int snd_sof_dbg_init(struct snd_sof_dev *sdev)
 {
+       struct snd_sof_pdata *plat_data = sdev->pdata;
        struct snd_sof_dsp_ops *ops = sof_ops(sdev);
        const struct snd_sof_debugfs_map *map;
+       struct dentry *fw_profile;
        int i;
        int err;
 
        /* use "sof" as top level debugFS dir */
        sdev->debugfs_root = debugfs_create_dir("sof", NULL);
 
+       /* expose firmware/topology prefix/names for test purposes */
+       fw_profile = debugfs_create_dir("fw_profile", sdev->debugfs_root);
+
+       debugfs_create_str("fw_path", 0444, fw_profile,
+                          (char **)&plat_data->fw_filename_prefix);
+       debugfs_create_str("fw_lib_path", 0444, fw_profile,
+                          (char **)&plat_data->fw_lib_prefix);
+       debugfs_create_str("tplg_path", 0444, fw_profile,
+                          (char **)&plat_data->tplg_filename_prefix);
+       debugfs_create_str("fw_name", 0444, fw_profile,
+                          (char **)&plat_data->fw_filename);
+       debugfs_create_str("tplg_name", 0444, fw_profile,
+                          (char **)&plat_data->tplg_filename);
+       debugfs_create_u32("ipc_type", 0444, fw_profile,
+                          (u32 *)&plat_data->ipc_type);
+
        /* init dfsentry list */
        INIT_LIST_HEAD(&sdev->dfsentry_list);
 
index b26ffe767fab553467897b4facc13931668b27fe..b14e508f1f315b19585ad6851f8fc5f4b1d3891a 100644 (file)
@@ -35,6 +35,9 @@ static const struct sof_dev_desc lnl_desc = {
        .default_fw_path = {
                [SOF_IPC_TYPE_4] = "intel/sof-ipc4/lnl",
        },
+       .default_lib_path = {
+               [SOF_IPC_TYPE_4] = "intel/sof-ipc4-lib/lnl",
+       },
        .default_tplg_path = {
                [SOF_IPC_TYPE_4] = "intel/sof-ipc4-tplg",
        },
index 35769dd7905ebe6f66492f650a72d8624712f28a..af0bf354cb209e216b60ec0097ac88fb08b21475 100644 (file)
@@ -434,4 +434,5 @@ const struct sof_ipc_pcm_ops ipc3_pcm_ops = {
        .trigger = sof_ipc3_pcm_trigger,
        .dai_link_fixup = sof_ipc3_pcm_dai_link_fixup,
        .reset_hw_params_during_stop = true,
+       .d0i3_supported_in_s0ix = true,
 };
index e915f9f87a6c35d74f1cf7096accca70dce688da..4594470ed08b1e6e95af6e2aaa62da418281ce97 100644 (file)
@@ -37,6 +37,25 @@ struct sof_ipc4_timestamp_info {
        snd_pcm_sframes_t delay;
 };
 
+/**
+ * struct sof_ipc4_pcm_stream_priv - IPC4 specific private data
+ * @time_info: pointer to time info struct if it is supported, otherwise NULL
+ * @chain_dma_allocated: indicates the ChainDMA allocation state
+ */
+struct sof_ipc4_pcm_stream_priv {
+       struct sof_ipc4_timestamp_info *time_info;
+
+       bool chain_dma_allocated;
+};
+
+static inline struct sof_ipc4_timestamp_info *
+sof_ipc4_sps_to_time_info(struct snd_sof_pcm_stream *sps)
+{
+       struct sof_ipc4_pcm_stream_priv *stream_priv = sps->private;
+
+       return stream_priv->time_info;
+}
+
 static int sof_ipc4_set_multi_pipeline_state(struct snd_sof_dev *sdev, u32 state,
                                             struct ipc4_pipeline_set_state_data *trigger_list)
 {
@@ -253,14 +272,17 @@ sof_ipc4_update_pipeline_state(struct snd_sof_dev *sdev, int state, int cmd,
  */
 
 static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev,
-                                     int direction,
+                                     struct snd_sof_pcm *spcm, int direction,
                                      struct snd_sof_pcm_stream_pipeline_list *pipeline_list,
                                      int state, int cmd)
 {
        struct sof_ipc4_fw_data *ipc4_data = sdev->private;
+       struct sof_ipc4_pcm_stream_priv *stream_priv;
        bool allocate, enable, set_fifo_size;
        struct sof_ipc4_msg msg = {{ 0 }};
-       int i;
+       int ret, i;
+
+       stream_priv = spcm->stream[direction].private;
 
        switch (state) {
        case SOF_IPC4_PIPE_RUNNING: /* Allocate and start chained dma */
@@ -281,6 +303,11 @@ static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev,
                set_fifo_size = false;
                break;
        case SOF_IPC4_PIPE_RESET: /* Disable and free chained DMA. */
+
+               /* ChainDMA can only be reset if it has been allocated */
+               if (!stream_priv->chain_dma_allocated)
+                       return 0;
+
                allocate = false;
                enable = false;
                set_fifo_size = false;
@@ -338,7 +365,12 @@ static int sof_ipc4_chain_dma_trigger(struct snd_sof_dev *sdev,
        if (enable)
                msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_ENABLE_MASK;
 
-       return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
+       ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
+       /* Update the ChainDMA allocation state */
+       if (!ret)
+               stream_priv->chain_dma_allocated = allocate;
+
+       return ret;
 }
 
 static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
@@ -378,7 +410,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
         * trigger function that handles the rest for the substream.
         */
        if (pipeline->use_chain_dma)
-               return sof_ipc4_chain_dma_trigger(sdev, substream->stream,
+               return sof_ipc4_chain_dma_trigger(sdev, spcm, substream->stream,
                                                  pipeline_list, state, cmd);
 
        /* allocate memory for the pipeline data */
@@ -452,7 +484,7 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
                 * Invalidate the stream_start_offset to make sure that it is
                 * going to be updated if the stream resumes
                 */
-               time_info = spcm->stream[substream->stream].private;
+               time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
                if (time_info)
                        time_info->stream_start_offset = SOF_IPC4_INVALID_STREAM_POSITION;
 
@@ -706,12 +738,16 @@ static int sof_ipc4_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
 static void sof_ipc4_pcm_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm)
 {
        struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
+       struct sof_ipc4_pcm_stream_priv *stream_priv;
        int stream;
 
        for_each_pcm_streams(stream) {
                pipeline_list = &spcm->stream[stream].pipeline_list;
                kfree(pipeline_list->pipelines);
                pipeline_list->pipelines = NULL;
+
+               stream_priv = spcm->stream[stream].private;
+               kfree(stream_priv->time_info);
                kfree(spcm->stream[stream].private);
                spcm->stream[stream].private = NULL;
        }
@@ -721,7 +757,8 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
 {
        struct snd_sof_pcm_stream_pipeline_list *pipeline_list;
        struct sof_ipc4_fw_data *ipc4_data = sdev->private;
-       struct sof_ipc4_timestamp_info *stream_info;
+       struct sof_ipc4_pcm_stream_priv *stream_priv;
+       struct sof_ipc4_timestamp_info *time_info;
        bool support_info = true;
        u32 abi_version;
        u32 abi_offset;
@@ -749,33 +786,41 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm
                        return -ENOMEM;
                }
 
+               stream_priv = kzalloc(sizeof(*stream_priv), GFP_KERNEL);
+               if (!stream_priv) {
+                       sof_ipc4_pcm_free(sdev, spcm);
+                       return -ENOMEM;
+               }
+
+               spcm->stream[stream].private = stream_priv;
+
                if (!support_info)
                        continue;
 
-               stream_info = kzalloc(sizeof(*stream_info), GFP_KERNEL);
-               if (!stream_info) {
+               time_info = kzalloc(sizeof(*time_info), GFP_KERNEL);
+               if (!time_info) {
                        sof_ipc4_pcm_free(sdev, spcm);
                        return -ENOMEM;
                }
 
-               spcm->stream[stream].private = stream_info;
+               stream_priv->time_info = time_info;
        }
 
        return 0;
 }
 
-static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *spcm)
+static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pcm_stream *sps)
 {
        struct sof_ipc4_copier *host_copier = NULL;
        struct sof_ipc4_copier *dai_copier = NULL;
        struct sof_ipc4_llp_reading_slot llp_slot;
-       struct sof_ipc4_timestamp_info *info;
+       struct sof_ipc4_timestamp_info *time_info;
        struct snd_soc_dapm_widget *widget;
        struct snd_sof_dai *dai;
        int i;
 
        /* find host & dai to locate info in memory window */
-       for_each_dapm_widgets(spcm->list, i, widget) {
+       for_each_dapm_widgets(sps->list, i, widget) {
                struct snd_sof_widget *swidget = widget->dobj.private;
 
                if (!swidget)
@@ -795,44 +840,44 @@ static void sof_ipc4_build_time_info(struct snd_sof_dev *sdev, struct snd_sof_pc
                return;
        }
 
-       info = spcm->private;
-       info->host_copier = host_copier;
-       info->dai_copier = dai_copier;
-       info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_gpdma_reading_slots) +
-                                   sdev->fw_info_box.offset;
+       time_info = sof_ipc4_sps_to_time_info(sps);
+       time_info->host_copier = host_copier;
+       time_info->dai_copier = dai_copier;
+       time_info->llp_offset = offsetof(struct sof_ipc4_fw_registers,
+                                        llp_gpdma_reading_slots) + sdev->fw_info_box.offset;
 
        /* find llp slot used by current dai */
        for (i = 0; i < SOF_IPC4_MAX_LLP_GPDMA_READING_SLOTS; i++) {
-               sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
+               sof_mailbox_read(sdev, time_info->llp_offset, &llp_slot, sizeof(llp_slot));
                if (llp_slot.node_id == dai_copier->data.gtw_cfg.node_id)
                        break;
 
-               info->llp_offset += sizeof(llp_slot);
+               time_info->llp_offset += sizeof(llp_slot);
        }
 
        if (i < SOF_IPC4_MAX_LLP_GPDMA_READING_SLOTS)
                return;
 
        /* if no llp gpdma slot is used, check aggregated sdw slot */
-       info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_sndw_reading_slots) +
-                                       sdev->fw_info_box.offset;
+       time_info->llp_offset = offsetof(struct sof_ipc4_fw_registers,
+                                        llp_sndw_reading_slots) + sdev->fw_info_box.offset;
        for (i = 0; i < SOF_IPC4_MAX_LLP_SNDW_READING_SLOTS; i++) {
-               sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
+               sof_mailbox_read(sdev, time_info->llp_offset, &llp_slot, sizeof(llp_slot));
                if (llp_slot.node_id == dai_copier->data.gtw_cfg.node_id)
                        break;
 
-               info->llp_offset += sizeof(llp_slot);
+               time_info->llp_offset += sizeof(llp_slot);
        }
 
        if (i < SOF_IPC4_MAX_LLP_SNDW_READING_SLOTS)
                return;
 
        /* check EVAD slot */
-       info->llp_offset = offsetof(struct sof_ipc4_fw_registers, llp_evad_reading_slot) +
-                                       sdev->fw_info_box.offset;
-       sof_mailbox_read(sdev, info->llp_offset, &llp_slot, sizeof(llp_slot));
+       time_info->llp_offset = offsetof(struct sof_ipc4_fw_registers,
+                                        llp_evad_reading_slot) + sdev->fw_info_box.offset;
+       sof_mailbox_read(sdev, time_info->llp_offset, &llp_slot, sizeof(llp_slot));
        if (llp_slot.node_id != dai_copier->data.gtw_cfg.node_id)
-               info->llp_offset = 0;
+               time_info->llp_offset = 0;
 }
 
 static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
@@ -849,7 +894,7 @@ static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
        if (!spcm)
                return -EINVAL;
 
-       time_info = spcm->stream[substream->stream].private;
+       time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
        /* delay calculation is not supported by current fw_reg ABI */
        if (!time_info)
                return 0;
@@ -864,7 +909,7 @@ static int sof_ipc4_pcm_hw_params(struct snd_soc_component *component,
 
 static int sof_ipc4_get_stream_start_offset(struct snd_sof_dev *sdev,
                                            struct snd_pcm_substream *substream,
-                                           struct snd_sof_pcm_stream *stream,
+                                           struct snd_sof_pcm_stream *sps,
                                            struct sof_ipc4_timestamp_info *time_info)
 {
        struct sof_ipc4_copier *host_copier = time_info->host_copier;
@@ -918,7 +963,7 @@ static int sof_ipc4_pcm_pointer(struct snd_soc_component *component,
        struct sof_ipc4_timestamp_info *time_info;
        struct sof_ipc4_llp_reading_slot llp;
        snd_pcm_uframes_t head_cnt, tail_cnt;
-       struct snd_sof_pcm_stream *stream;
+       struct snd_sof_pcm_stream *sps;
        u64 dai_cnt, host_cnt, host_ptr;
        struct snd_sof_pcm *spcm;
        int ret;
@@ -927,8 +972,8 @@ static int sof_ipc4_pcm_pointer(struct snd_soc_component *component,
        if (!spcm)
                return -EOPNOTSUPP;
 
-       stream = &spcm->stream[substream->stream];
-       time_info = stream->private;
+       sps = &spcm->stream[substream->stream];
+       time_info = sof_ipc4_sps_to_time_info(sps);
        if (!time_info)
                return -EOPNOTSUPP;
 
@@ -938,7 +983,7 @@ static int sof_ipc4_pcm_pointer(struct snd_soc_component *component,
         * the statistics is complete. And it will not change after the first initiailization.
         */
        if (time_info->stream_start_offset == SOF_IPC4_INVALID_STREAM_POSITION) {
-               ret = sof_ipc4_get_stream_start_offset(sdev, substream, stream, time_info);
+               ret = sof_ipc4_get_stream_start_offset(sdev, substream, sps, time_info);
                if (ret < 0)
                        return -EOPNOTSUPP;
        }
@@ -1030,15 +1075,13 @@ static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component,
 {
        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
        struct sof_ipc4_timestamp_info *time_info;
-       struct snd_sof_pcm_stream *stream;
        struct snd_sof_pcm *spcm;
 
        spcm = snd_sof_find_spcm_dai(component, rtd);
        if (!spcm)
                return 0;
 
-       stream = &spcm->stream[substream->stream];
-       time_info = stream->private;
+       time_info = sof_ipc4_sps_to_time_info(&spcm->stream[substream->stream]);
        /*
         * Report the stored delay value calculated in the pointer callback.
         * In the unlikely event that the calculation was skipped/aborted, the
index f03cee94bce62642e3c419d4f956a2011ea4dd3f..8804e00e7251b9724054b119509698a3a12899bf 100644 (file)
@@ -325,14 +325,13 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
                        ipc_first = true;
                break;
        case SNDRV_PCM_TRIGGER_SUSPEND:
-               if (sdev->system_suspend_target == SOF_SUSPEND_S0IX &&
+               /*
+                * If DSP D0I3 is allowed during S0iX, set the suspend_ignored flag for
+                * D0I3-compatible streams to keep the firmware pipeline running
+                */
+               if (pcm_ops && pcm_ops->d0i3_supported_in_s0ix &&
+                   sdev->system_suspend_target == SOF_SUSPEND_S0IX &&
                    spcm->stream[substream->stream].d0i3_compatible) {
-                       /*
-                        * trap the event, not sending trigger stop to
-                        * prevent the FW pipelines from being stopped,
-                        * and mark the flag to ignore the upcoming DAPM
-                        * PM events.
-                        */
                        spcm->stream[substream->stream].suspend_ignored = true;
                        return 0;
                }
index 86bbb531e142c72be1ca5d710c466d16c9058734..499b6084b52637f12623172b0b17d027a41c08d4 100644 (file)
@@ -116,6 +116,7 @@ struct snd_sof_dai_config_data {
  *                               triggers. The FW keeps the host DMA running in this case and
  *                               therefore the host must do the same and should stop the DMA during
  *                               hw_free.
+ * @d0i3_supported_in_s0ix: Allow DSP D0I3 during S0iX
  */
 struct sof_ipc_pcm_ops {
        int (*hw_params)(struct snd_soc_component *component, struct snd_pcm_substream *substream,
@@ -135,6 +136,7 @@ struct sof_ipc_pcm_ops {
        bool reset_hw_params_during_stop;
        bool ipc_first_on_start;
        bool platform_stop_during_hw_free;
+       bool d0i3_supported_in_s0ix;
 };
 
 /**
index aa37c4ab0adbd9b47d2228cb4977e78ebf97b576..21cd41fec7a9cb932ecdc479ca41394349c48ffc 100644 (file)
@@ -1,8 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 //
 // tegra186_dspk.c - Tegra186 DSPK driver
-//
-// Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved.
 
 #include <linux/clk.h>
 #include <linux/device.h>
@@ -241,14 +240,14 @@ static int tegra186_dspk_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       cif_conf.client_bits = TEGRA_ACIF_BITS_24;
-
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
                cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
+               cif_conf.client_bits = TEGRA_ACIF_BITS_16;
                break;
        case SNDRV_PCM_FORMAT_S32_LE:
                cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
+               cif_conf.client_bits = TEGRA_ACIF_BITS_24;
                break;
        default:
                dev_err(dev, "unsupported format!\n");
index b892d66f78470a6430b7096efdafab202992dbd2..1e760c3155213db093ff09a12b922eb43c3ba4c4 100644 (file)
@@ -2417,12 +2417,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
 
        mcasp_reparent_fck(pdev);
 
-       ret = devm_snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
-                                             &davinci_mcasp_dai[mcasp->op_mode], 1);
-
-       if (ret != 0)
-               goto err;
-
        ret = davinci_mcasp_get_dma_type(mcasp);
        switch (ret) {
        case PCM_EDMA:
@@ -2449,6 +2443,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
                goto err;
        }
 
+       ret = devm_snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
+                                             &davinci_mcasp_dai[mcasp->op_mode], 1);
+
+       if (ret != 0)
+               goto err;
+
 no_audio:
        ret = davinci_mcasp_init_gpiochip(mcasp);
        if (ret) {
index 4a41856938a8889403278a4ad44c599d835b887a..1b29030021eeba71e34eeb8adcf69278f11a1dda 100644 (file)
@@ -41,7 +41,7 @@ static char *_get_cpuid(void)
        char *mimpid = NULL;
        char *cpuid = NULL;
        int read;
-       unsigned long line_sz;
+       size_t line_sz;
        FILE *cpuinfo;
 
        cpuinfo = fopen(CPUINFO, "r");
index 61c69297e7978fceed700be3ad43a7a870d20de2..3482248aa34424e1d690ecea1faef822d152edd3 100644 (file)
@@ -1001,6 +1001,7 @@ static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)
        struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
        struct cxl_dev_state *cxlds = cxlmd->cxlds;
        struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
+       struct access_coordinate ep_c[ACCESS_COORDINATE_MAX];
        struct range pmem_range = {
                .start = cxlds->pmem_res.start,
                .end = cxlds->pmem_res.end,
@@ -1020,6 +1021,12 @@ static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)
                dpa_perf_setup(port, &pmem_range, &mds->pmem_perf);
 
        cxl_memdev_update_perf(cxlmd);
+
+       /*
+        * This function is here to only test the topology iterator. It serves
+        * no other purpose.
+        */
+       cxl_endpoint_get_perf_coordinates(port, ep_c);
 }
 
 static struct cxl_mock_ops cxl_mock_ops = {
index 12a1d525978a2a3e99c117b3696a9069b19432af..c87758030ff791ca84d2b3fe1380f01ea2afc69d 100644 (file)
@@ -13,7 +13,7 @@ if not os.path.isfile(OPENSBI_PATH):
 
 QEMU_ARCH = QemuArchParams(linux_arch='riscv',
                           kconfig='''
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
index c5c9d05f29da95e4b7d0b462675fde9dcc028924..c0a2bb785b92b41f2f734afa39661adcde51a433 100644 (file)
@@ -18,6 +18,8 @@
 #define pr_info printk
 #define pr_debug printk
 #define pr_cont printk
+#define schedule()
+#define PAGE_SHIFT     12
 
 #define __acquires(x)
 #define __releases(x)
index 39ad96a18123f626c311aaa2fdf8213594b7d67d..edcd26106557b478eea1527077ffde97347c9012 100644 (file)
@@ -205,6 +205,9 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
        case 5: return (void *)~(1ull << 30);   /* trigger extable */
        case 6: return &f;                      /* valid addr */
        case 7: return (void *)((long)&f | 1);  /* kernel tricks */
+#ifdef CONFIG_X86_64
+       case 8: return (void *)VSYSCALL_ADDR;   /* vsyscall page address */
+#endif
        default: return NULL;
        }
 }
index c59e4adb905df61494db41d99355fbac5d742bab..991c473e385938030340db7ed7a998c8bff62b5d 100644 (file)
 #include "../kselftest_harness.h"
 #include "../clone3/clone3_selftests.h"
 
+
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+
+#ifndef F_DUPFD_QUERY
+#define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3)
+#endif
+
 static inline int sys_close_range(unsigned int fd, unsigned int max_fd,
                                  unsigned int flags)
 {
@@ -45,6 +54,15 @@ TEST(core_close_range)
                        SKIP(return, "close_range() syscall not supported");
        }
 
+       for (i = 0; i < 100; i++) {
+               ret = fcntl(open_fds[i], F_DUPFD_QUERY, open_fds[i + 1]);
+               if (ret < 0) {
+                       EXPECT_EQ(errno, EINVAL);
+               } else {
+                       EXPECT_EQ(ret, 0);
+               }
+       }
+
        EXPECT_EQ(0, sys_close_range(open_fds[0], open_fds[50], 0));
 
        for (i = 0; i <= 50; i++)
@@ -358,7 +376,7 @@ TEST(close_range_cloexec_unshare)
  */
 TEST(close_range_cloexec_syzbot)
 {
-       int fd1, fd2, fd3, flags, ret, status;
+       int fd1, fd2, fd3, fd4, flags, ret, status;
        pid_t pid;
        struct __clone_args args = {
                .flags = CLONE_FILES,
@@ -372,6 +390,13 @@ TEST(close_range_cloexec_syzbot)
        fd2 = dup2(fd1, 1000);
        EXPECT_GT(fd2, 0);
 
+       flags = fcntl(fd1, F_DUPFD_QUERY, fd2);
+       if (flags < 0) {
+               EXPECT_EQ(errno, EINVAL);
+       } else {
+               EXPECT_EQ(flags, 1);
+       }
+
        pid = sys_clone3(&args, sizeof(args));
        ASSERT_GE(pid, 0);
 
@@ -396,6 +421,15 @@ TEST(close_range_cloexec_syzbot)
                fd3 = dup2(fd1, 42);
                EXPECT_GT(fd3, 0);
 
+               flags = fcntl(fd1, F_DUPFD_QUERY, fd3);
+               if (flags < 0) {
+                       EXPECT_EQ(errno, EINVAL);
+               } else {
+                       EXPECT_EQ(flags, 1);
+               }
+
+
+
                /*
                         * Duplicating the file descriptor must remove the
                         * FD_CLOEXEC flag.
@@ -426,6 +460,24 @@ TEST(close_range_cloexec_syzbot)
        fd3 = dup2(fd1, 42);
        EXPECT_GT(fd3, 0);
 
+       flags = fcntl(fd1, F_DUPFD_QUERY, fd3);
+       if (flags < 0) {
+               EXPECT_EQ(errno, EINVAL);
+       } else {
+               EXPECT_EQ(flags, 1);
+       }
+
+       fd4 = open("/dev/null", O_RDWR);
+       EXPECT_GT(fd4, 0);
+
+       /* Same inode, different file pointers. */
+       flags = fcntl(fd1, F_DUPFD_QUERY, fd4);
+       if (flags < 0) {
+               EXPECT_EQ(errno, EINVAL);
+       } else {
+               EXPECT_EQ(flags, 0);
+       }
+
        flags = fcntl(fd3, F_GETFD);
        EXPECT_GT(flags, -1);
        EXPECT_EQ(flags & FD_CLOEXEC, 0);
@@ -433,6 +485,7 @@ TEST(close_range_cloexec_syzbot)
        EXPECT_EQ(close(fd1), 0);
        EXPECT_EQ(close(fd2), 0);
        EXPECT_EQ(close(fd3), 0);
+       EXPECT_EQ(close(fd4), 0);
 }
 
 /*
index d98702b6955df24e72366f2246ad5b3da7951b5a..3c8f2965c2850c8fa0a95259433857e4a324641b 100644 (file)
@@ -66,6 +66,8 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <setjmp.h>
+#include <syscall.h>
+#include <linux/sched.h>
 
 #include "kselftest.h"
 
 #  define TH_LOG_ENABLED 1
 #endif
 
+/* Wait for the child process to end but without sharing memory mapping. */
+static inline pid_t clone3_vfork(void)
+{
+       struct clone_args args = {
+               .flags = CLONE_VFORK,
+               .exit_signal = SIGCHLD,
+       };
+
+       return syscall(__NR_clone3, &args, sizeof(args));
+}
+
 /**
  * TH_LOG()
  *
  * A bare "return;" statement may be used to return early.
  */
 #define FIXTURE_TEARDOWN(fixture_name) \
+       static const bool fixture_name##_teardown_parent; \
+       __FIXTURE_TEARDOWN(fixture_name)
+
+/**
+ * FIXTURE_TEARDOWN_PARENT()
+ * *_metadata* is included so that EXPECT_*, ASSERT_* etc. work correctly.
+ *
+ * @fixture_name: fixture name
+ *
+ * .. code-block:: c
+ *
+ *     FIXTURE_TEARDOWN_PARENT(fixture_name) { implementation }
+ *
+ * Same as FIXTURE_TEARDOWN() but run this code in a parent process.  This
+ * enables the test process to drop its privileges without impacting the
+ * related FIXTURE_TEARDOWN_PARENT() (e.g. to remove files from a directory
+ * where write access was dropped).
+ *
+ * To make it possible for the parent process to use *self*, share (MAP_SHARED)
+ * the fixture data between all forked processes.
+ */
+#define FIXTURE_TEARDOWN_PARENT(fixture_name) \
+       static const bool fixture_name##_teardown_parent = true; \
+       __FIXTURE_TEARDOWN(fixture_name)
+
+#define __FIXTURE_TEARDOWN(fixture_name) \
        void fixture_name##_teardown( \
                struct __test_metadata __attribute__((unused)) *_metadata, \
                FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
  * variant.
  */
 #define FIXTURE_VARIANT_ADD(fixture_name, variant_name) \
-       extern FIXTURE_VARIANT(fixture_name) \
+       extern const FIXTURE_VARIANT(fixture_name) \
                _##fixture_name##_##variant_name##_variant; \
        static struct __fixture_variant_metadata \
                _##fixture_name##_##variant_name##_object = \
                __register_fixture_variant(&_##fixture_name##_fixture_object, \
                        &_##fixture_name##_##variant_name##_object);    \
        } \
-       FIXTURE_VARIANT(fixture_name) \
+       const FIXTURE_VARIANT(fixture_name) \
                _##fixture_name##_##variant_name##_variant =
 
 /**
  * Very similar to TEST() except that *self* is the setup instance of fixture's
  * datatype exposed for use by the implementation.
  *
- * The @test_name code is run in a separate process sharing the same memory
- * (i.e. vfork), which means that the test process can update its privileges
- * without impacting the related FIXTURE_TEARDOWN() (e.g. to remove files from
- * a directory where write access was dropped).
+ * The _metadata object is shared (MAP_SHARED) with all the potential forked
+ * processes, which enables them to use EXCEPT_*() and ASSERT_*().
+ *
+ * The *self* object is only shared with the potential forked processes if
+ * FIXTURE_TEARDOWN_PARENT() is used instead of FIXTURE_TEARDOWN().
  */
 #define TEST_F(fixture_name, test_name) \
        __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
                struct __fixture_variant_metadata *variant) \
        { \
                /* fixture data is alloced, setup, and torn down per call. */ \
-               FIXTURE_DATA(fixture_name) self; \
+               FIXTURE_DATA(fixture_name) self_private, *self = NULL; \
                pid_t child = 1; \
                int status = 0; \
-               bool jmp = false; \
-               memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
+               /* Makes sure there is only one teardown, even when child forks again. */ \
+               bool *teardown = mmap(NULL, sizeof(*teardown), \
+                       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \
+               *teardown = false; \
+               if (sizeof(*self) > 0) { \
+                       if (fixture_name##_teardown_parent) { \
+                               self = mmap(NULL, sizeof(*self), PROT_READ | PROT_WRITE, \
+                                       MAP_SHARED | MAP_ANONYMOUS, -1, 0); \
+                       } else { \
+                               memset(&self_private, 0, sizeof(self_private)); \
+                               self = &self_private; \
+                       } \
+               } \
                if (setjmp(_metadata->env) == 0) { \
-                       /* Use the same _metadata. */ \
-                       child = vfork(); \
+                       /* _metadata and potentially self are shared with all forks. */ \
+                       child = clone3_vfork(); \
                        if (child == 0) { \
-                               fixture_name##_setup(_metadata, &self, variant->data); \
+                               fixture_name##_setup(_metadata, self, variant->data); \
                                /* Let setup failure terminate early. */ \
                                if (_metadata->exit_code) \
                                        _exit(0); \
                                _metadata->setup_completed = true; \
-                               fixture_name##_##test_name(_metadata, &self, variant->data); \
+                               fixture_name##_##test_name(_metadata, self, variant->data); \
                        } else if (child < 0 || child != waitpid(child, &status, 0)) { \
                                ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
                                _metadata->exit_code = KSFT_FAIL; \
                        } \
                } \
-               else \
-                       jmp = true; \
                if (child == 0) { \
-                       if (_metadata->setup_completed && !_metadata->teardown_parent && !jmp) \
-                               fixture_name##_teardown(_metadata, &self, variant->data); \
+                       if (_metadata->setup_completed && !fixture_name##_teardown_parent && \
+                                       __sync_bool_compare_and_swap(teardown, false, true)) \
+                               fixture_name##_teardown(_metadata, self, variant->data); \
                        _exit(0); \
                } \
-               if (_metadata->setup_completed && _metadata->teardown_parent) \
-                       fixture_name##_teardown(_metadata, &self, variant->data); \
-               if (!WIFEXITED(status) && WIFSIGNALED(status)) \
+               if (_metadata->setup_completed && fixture_name##_teardown_parent && \
+                               __sync_bool_compare_and_swap(teardown, false, true)) \
+                       fixture_name##_teardown(_metadata, self, variant->data); \
+               munmap(teardown, sizeof(*teardown)); \
+               if (self && fixture_name##_teardown_parent) \
+                       munmap(self, sizeof(*self)); \
+               if (WIFEXITED(status)) { \
+                       if (WEXITSTATUS(status)) \
+                               _metadata->exit_code = WEXITSTATUS(status); \
+               } else if (WIFSIGNALED(status)) { \
                        /* Forward signal to __wait_for_test(). */ \
                        kill(getpid(), WTERMSIG(status)); \
+               } \
                __test_check_assert(_metadata); \
        } \
-       static struct __test_metadata \
-                     _##fixture_name##_##test_name##_object = { \
-               .name = #test_name, \
-               .fn = &wrapper_##fixture_name##_##test_name, \
-               .fixture = &_##fixture_name##_fixture_object, \
-               .termsig = signal, \
-               .timeout = tmout, \
-               .teardown_parent = false, \
-        }; \
+       static struct __test_metadata *_##fixture_name##_##test_name##_object; \
        static void __attribute__((constructor)) \
                        _register_##fixture_name##_##test_name(void) \
        { \
-               __register_test(&_##fixture_name##_##test_name##_object); \
+               struct __test_metadata *object = mmap(NULL, sizeof(*object), \
+                       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); \
+               object->name = #test_name; \
+               object->fn = &wrapper_##fixture_name##_##test_name; \
+               object->fixture = &_##fixture_name##_fixture_object; \
+               object->termsig = signal; \
+               object->timeout = tmout; \
+               _##fixture_name##_##test_name##_object = object; \
+               __register_test(object); \
        } \
        static void fixture_name##_##test_name( \
                struct __test_metadata __attribute__((unused)) *_metadata, \
@@ -833,11 +891,12 @@ struct __test_xfail {
        { \
                .fixture = &_##fixture_name##_fixture_object, \
                .variant = &_##fixture_name##_##variant_name##_object, \
-               .test = &_##fixture_name##_##test_name##_object, \
        }; \
        static void __attribute__((constructor)) \
                _register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \
        { \
+               _##fixture_name##_##variant_name##_##test_name##_xfail.test = \
+                       _##fixture_name##_##test_name##_object; \
                __register_xfail(&_##fixture_name##_##variant_name##_##test_name##_xfail); \
        }
 
@@ -880,7 +939,6 @@ struct __test_metadata {
        bool timed_out; /* did this test timeout instead of exiting? */
        bool aborted;   /* stopped test due to failed ASSERT */
        bool setup_completed; /* did setup finish? */
-       bool teardown_parent; /* run teardown in a parent process */
        jmp_buf env;    /* for exiting out of test early */
        struct __test_results *results;
        struct __test_metadata *prev, *next;
@@ -1164,6 +1222,9 @@ void __run_test(struct __fixture_metadata *f,
        /* reset test struct */
        t->exit_code = KSFT_PASS;
        t->trigger = 0;
+       t->aborted = false;
+       t->setup_completed = false;
+       memset(t->env, 0, sizeof(t->env));
        memset(t->results->reason, 0, sizeof(t->results->reason));
 
        if (asprintf(&test_name, "%s%s%s.%s", f->name,
@@ -1179,7 +1240,7 @@ void __run_test(struct __fixture_metadata *f,
        fflush(stdout);
        fflush(stderr);
 
-       t->pid = fork();
+       t->pid = clone3_vfork();
        if (t->pid < 0) {
                ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
                t->exit_code = KSFT_FAIL;
index eef816b80993f528569f0de79b5f5e5fcda0e289..ca917c71ff602da5ab0805c4cee51e0df5d185e5 100644 (file)
@@ -84,6 +84,18 @@ static struct vm_gic vm_gic_create_with_vcpus(uint32_t gic_dev_type,
        return v;
 }
 
+static struct vm_gic vm_gic_create_barebones(uint32_t gic_dev_type)
+{
+       struct vm_gic v;
+
+       v.gic_dev_type = gic_dev_type;
+       v.vm = vm_create_barebones();
+       v.gic_fd = kvm_create_device(v.vm, gic_dev_type);
+
+       return v;
+}
+
+
 static void vm_gic_destroy(struct vm_gic *v)
 {
        close(v->gic_fd);
@@ -357,6 +369,40 @@ static void test_vcpus_then_vgic(uint32_t gic_dev_type)
        vm_gic_destroy(&v);
 }
 
+#define KVM_VGIC_V2_ATTR(offset, cpu) \
+       (FIELD_PREP(KVM_DEV_ARM_VGIC_OFFSET_MASK, offset) | \
+        FIELD_PREP(KVM_DEV_ARM_VGIC_CPUID_MASK, cpu))
+
+#define GIC_CPU_CTRL   0x00
+
+static void test_v2_uaccess_cpuif_no_vcpus(void)
+{
+       struct vm_gic v;
+       u64 val = 0;
+       int ret;
+
+       v = vm_gic_create_barebones(KVM_DEV_TYPE_ARM_VGIC_V2);
+       subtest_dist_rdist(&v);
+
+       ret = __kvm_has_device_attr(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
+                                   KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0));
+       TEST_ASSERT(ret && errno == EINVAL,
+                   "accessed non-existent CPU interface, want errno: %i",
+                   EINVAL);
+       ret = __kvm_device_attr_get(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
+                                   KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0), &val);
+       TEST_ASSERT(ret && errno == EINVAL,
+                   "accessed non-existent CPU interface, want errno: %i",
+                   EINVAL);
+       ret = __kvm_device_attr_set(v.gic_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
+                                   KVM_VGIC_V2_ATTR(GIC_CPU_CTRL, 0), &val);
+       TEST_ASSERT(ret && errno == EINVAL,
+                   "accessed non-existent CPU interface, want errno: %i",
+                   EINVAL);
+
+       vm_gic_destroy(&v);
+}
+
 static void test_v3_new_redist_regions(void)
 {
        struct kvm_vcpu *vcpus[NR_VCPUS];
@@ -675,6 +721,9 @@ void run_tests(uint32_t gic_dev_type)
        test_vcpus_then_vgic(gic_dev_type);
        test_vgic_then_vcpus(gic_dev_type);
 
+       if (VGIC_DEV_IS_V2(gic_dev_type))
+               test_v2_uaccess_cpuif_no_vcpus();
+
        if (VGIC_DEV_IS_V3(gic_dev_type)) {
                test_v3_new_redist_regions();
                test_v3_typer_accesses();
index 9a6036fbf2893ff32de7a7778fefb0577672f9b7..27744524df519ac86de7cb4a183622dff66c7b6e 100644 (file)
@@ -9,6 +9,7 @@
 
 #define _GNU_SOURCE
 #include <fcntl.h>
+#include <libgen.h>
 #include <linux/landlock.h>
 #include <linux/magic.h>
 #include <sched.h>
@@ -285,15 +286,21 @@ static void prepare_layout_opt(struct __test_metadata *const _metadata,
 
 static void prepare_layout(struct __test_metadata *const _metadata)
 {
-       _metadata->teardown_parent = true;
-
        prepare_layout_opt(_metadata, &mnt_tmp);
 }
 
 static void cleanup_layout(struct __test_metadata *const _metadata)
 {
        set_cap(_metadata, CAP_SYS_ADMIN);
-       EXPECT_EQ(0, umount(TMP_DIR));
+       if (umount(TMP_DIR)) {
+               /*
+                * According to the test environment, the mount point of the
+                * current directory may be shared or not, which changes the
+                * visibility of the nested TMP_DIR mount point for the test's
+                * parent process doing this cleanup.
+                */
+               ASSERT_EQ(EINVAL, errno);
+       }
        clear_cap(_metadata, CAP_SYS_ADMIN);
        EXPECT_EQ(0, remove_path(TMP_DIR));
 }
@@ -307,7 +314,7 @@ FIXTURE_SETUP(layout0)
        prepare_layout(_metadata);
 }
 
-FIXTURE_TEARDOWN(layout0)
+FIXTURE_TEARDOWN_PARENT(layout0)
 {
        cleanup_layout(_metadata);
 }
@@ -370,7 +377,7 @@ FIXTURE_SETUP(layout1)
        create_layout1(_metadata);
 }
 
-FIXTURE_TEARDOWN(layout1)
+FIXTURE_TEARDOWN_PARENT(layout1)
 {
        remove_layout1(_metadata);
 
@@ -3683,7 +3690,7 @@ FIXTURE_SETUP(ftruncate)
        create_file(_metadata, file1_s1d1);
 }
 
-FIXTURE_TEARDOWN(ftruncate)
+FIXTURE_TEARDOWN_PARENT(ftruncate)
 {
        EXPECT_EQ(0, remove_path(file1_s1d1));
        cleanup_layout(_metadata);
@@ -3861,7 +3868,7 @@ FIXTURE_SETUP(layout1_bind)
        clear_cap(_metadata, CAP_SYS_ADMIN);
 }
 
-FIXTURE_TEARDOWN(layout1_bind)
+FIXTURE_TEARDOWN_PARENT(layout1_bind)
 {
        /* umount(dir_s2d2)) is handled by namespace lifetime. */
 
@@ -4266,7 +4273,7 @@ FIXTURE_SETUP(layout2_overlay)
        clear_cap(_metadata, CAP_SYS_ADMIN);
 }
 
-FIXTURE_TEARDOWN(layout2_overlay)
+FIXTURE_TEARDOWN_PARENT(layout2_overlay)
 {
        if (self->skip_test)
                SKIP(return, "overlayfs is not supported (teardown)");
@@ -4616,7 +4623,6 @@ FIXTURE(layout3_fs)
 {
        bool has_created_dir;
        bool has_created_file;
-       char *dir_path;
        bool skip_test;
 };
 
@@ -4675,11 +4681,24 @@ FIXTURE_VARIANT_ADD(layout3_fs, hostfs) {
        .cwd_fs_magic = HOSTFS_SUPER_MAGIC,
 };
 
+static char *dirname_alloc(const char *path)
+{
+       char *dup;
+
+       if (!path)
+               return NULL;
+
+       dup = strdup(path);
+       if (!dup)
+               return NULL;
+
+       return dirname(dup);
+}
+
 FIXTURE_SETUP(layout3_fs)
 {
        struct stat statbuf;
-       const char *slash;
-       size_t dir_len;
+       char *dir_path = dirname_alloc(variant->file_path);
 
        if (!supports_filesystem(variant->mnt.type) ||
            !cwd_matches_fs(variant->cwd_fs_magic)) {
@@ -4687,27 +4706,15 @@ FIXTURE_SETUP(layout3_fs)
                SKIP(return, "this filesystem is not supported (setup)");
        }
 
-       _metadata->teardown_parent = true;
-
-       slash = strrchr(variant->file_path, '/');
-       ASSERT_NE(slash, NULL);
-       dir_len = (size_t)slash - (size_t)variant->file_path;
-       ASSERT_LT(0, dir_len);
-       self->dir_path = malloc(dir_len + 1);
-       self->dir_path[dir_len] = '\0';
-       strncpy(self->dir_path, variant->file_path, dir_len);
-
        prepare_layout_opt(_metadata, &variant->mnt);
 
        /* Creates directory when required. */
-       if (stat(self->dir_path, &statbuf)) {
+       if (stat(dir_path, &statbuf)) {
                set_cap(_metadata, CAP_DAC_OVERRIDE);
-               EXPECT_EQ(0, mkdir(self->dir_path, 0700))
+               EXPECT_EQ(0, mkdir(dir_path, 0700))
                {
                        TH_LOG("Failed to create directory \"%s\": %s",
-                              self->dir_path, strerror(errno));
-                       free(self->dir_path);
-                       self->dir_path = NULL;
+                              dir_path, strerror(errno));
                }
                self->has_created_dir = true;
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
@@ -4728,9 +4735,11 @@ FIXTURE_SETUP(layout3_fs)
                self->has_created_file = true;
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
        }
+
+       free(dir_path);
 }
 
-FIXTURE_TEARDOWN(layout3_fs)
+FIXTURE_TEARDOWN_PARENT(layout3_fs)
 {
        if (self->skip_test)
                SKIP(return, "this filesystem is not supported (teardown)");
@@ -4746,16 +4755,17 @@ FIXTURE_TEARDOWN(layout3_fs)
        }
 
        if (self->has_created_dir) {
+               char *dir_path = dirname_alloc(variant->file_path);
+
                set_cap(_metadata, CAP_DAC_OVERRIDE);
                /*
                 * Don't check for error because the directory might already
                 * have been removed (cf. release_inode test).
                 */
-               rmdir(self->dir_path);
+               rmdir(dir_path);
                clear_cap(_metadata, CAP_DAC_OVERRIDE);
+               free(dir_path);
        }
-       free(self->dir_path);
-       self->dir_path = NULL;
 
        cleanup_layout(_metadata);
 }
@@ -4822,7 +4832,10 @@ TEST_F_FORK(layout3_fs, tag_inode_dir_mnt)
 
 TEST_F_FORK(layout3_fs, tag_inode_dir_child)
 {
-       layer3_fs_tag_inode(_metadata, self, variant, self->dir_path);
+       char *dir_path = dirname_alloc(variant->file_path);
+
+       layer3_fs_tag_inode(_metadata, self, variant, dir_path);
+       free(dir_path);
 }
 
 TEST_F_FORK(layout3_fs, tag_inode_file)
@@ -4849,9 +4862,13 @@ TEST_F_FORK(layout3_fs, release_inodes)
        if (self->has_created_file)
                EXPECT_EQ(0, remove_path(variant->file_path));
 
-       if (self->has_created_dir)
+       if (self->has_created_dir) {
+               char *dir_path = dirname_alloc(variant->file_path);
+
                /* Don't check for error because of cgroup specificities. */
-               remove_path(self->dir_path);
+               remove_path(dir_path);
+               free(dir_path);
+       }
 
        ruleset_fd =
                create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
index eb5f39a2668b44cfdb4520ee3d4afab790b5042c..410495e0a611070b5b59e63ca4f9edfd9011b7c5 100644 (file)
@@ -12,7 +12,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
 else
 uname_M := $(shell echo $(CROSS_COMPILE) | grep -o '^[a-z0-9]\+')
 endif
-ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/ppc64/')
+ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/powerpc/')
 endif
 
 # Without this, failed build products remain, with up-to-date timestamps,
@@ -98,13 +98,13 @@ TEST_GEN_FILES += $(BINARIES_64)
 endif
 else
 
-ifneq (,$(findstring $(ARCH),ppc64))
+ifneq (,$(findstring $(ARCH),powerpc))
 TEST_GEN_FILES += protection_keys
 endif
 
 endif
 
-ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sparc64 x86_64))
+ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64))
 TEST_GEN_FILES += va_high_addr_switch
 TEST_GEN_FILES += virtual_address_range
 TEST_GEN_FILES += write_to_hugetlbfs
index 8533393a4f1869f156ea1a47a76d63ad1fb1b712..02b986c9c247d6eb840d913c4a6b26db38cd01a1 100755 (executable)
@@ -154,17 +154,9 @@ setup_topo()
                setup_topo_ns $ns
        done
 
-       ip link add name veth0 type veth peer name veth1
-       ip link set dev veth0 netns $h1 name eth0
-       ip link set dev veth1 netns $sw1 name swp1
-
-       ip link add name veth0 type veth peer name veth1
-       ip link set dev veth0 netns $sw1 name veth0
-       ip link set dev veth1 netns $sw2 name veth0
-
-       ip link add name veth0 type veth peer name veth1
-       ip link set dev veth0 netns $h2 name eth0
-       ip link set dev veth1 netns $sw2 name swp1
+       ip -n $h1 link add name eth0 type veth peer name swp1 netns $sw1
+       ip -n $sw1 link add name veth0 type veth peer name veth0 netns $sw2
+       ip -n $h2 link add name eth0 type veth peer name swp1 netns $sw2
 }
 
 setup_host_common()
index f6f2965e17af1f4518c840fb57a25f25bee06ca5..6133524710f790c1f83af6f2b628de9b62eee6c3 100644 (file)
@@ -3,5 +3,7 @@ CONFIG_IPC_NS=y
 CONFIG_USER_NS=y
 CONFIG_PID_NS=y
 CONFIG_NET_NS=y
+CONFIG_TIME_NS=y
+CONFIG_GENERIC_VDSO_TIME_NS=y
 CONFIG_CGROUPS=y
 CONFIG_CHECKPOINT_RESTORE=y
index 6e2f2cd400caa5a4be93bf0353282bba63d7b132..47746b0c6acdf709a77653a51eb942474150fa25 100644 (file)
@@ -158,7 +158,7 @@ FIXTURE_SETUP(current_nsset)
        /* Create task that exits right away. */
        self->child_pid_exited = create_child(&self->child_pidfd_exited,
                                              CLONE_NEWUSER | CLONE_NEWNET);
-       EXPECT_GT(self->child_pid_exited, 0);
+       EXPECT_GE(self->child_pid_exited, 0);
 
        if (self->child_pid_exited == 0)
                _exit(EXIT_SUCCESS);
index bbac5f4b03d04bfbda25da59a175cb09ca2f6fd2..990d24696fd3418f22d1dedefdbf4fa3d1f71e90 100755 (executable)
@@ -391,7 +391,7 @@ __EOF__
                forceflavor="`echo $flavor | sed -e 's/^CONFIG/CONFIG_FORCE/'`"
                deselectedflavors="`grep -v $flavor $T/rcutasksflavors | tr '\012' ' ' | tr -s ' ' | sed -e 's/ *$//'`"
                echo " --- Running RCU Tasks Trace flavor $flavor `date`" >> $rtfdir/log
-               tools/testing/selftests/rcutorture/bin/kvm.sh --datestamp "$ds/results-rcutasksflavors/$flavor" --buildonly --configs "TINY01 TREE04" --kconfig "CONFIG_RCU_EXPERT=y CONFIG_RCU_SCALE_TEST=y $forceflavor=y $deselectedflavors" --trust-make > $T/$flavor.out 2>&1
+               tools/testing/selftests/rcutorture/bin/kvm.sh --datestamp "$ds/results-rcutasksflavors/$flavor" --buildonly --configs "TINY01 TREE04" --kconfig "CONFIG_RCU_EXPERT=y CONFIG_RCU_SCALE_TEST=y CONFIG_KPROBES=n CONFIG_RCU_TRACE=n CONFIG_TRACING=n CONFIG_BLK_DEV_IO_TRACE=n CONFIG_UPROBE_EVENTS=n $forceflavor=y $deselectedflavors" --trust-make > $T/$flavor.out 2>&1
                retcode=$?
                if test "$retcode" -ne 0
                then
@@ -425,7 +425,7 @@ fi
 if test "$do_scftorture" = "yes"
 then
        # Scale memory based on the number of CPUs.
-       scfmem=$((2+HALF_ALLOTED_CPUS/16))
+       scfmem=$((3+HALF_ALLOTED_CPUS/16))
        torture_bootargs="scftorture.nthreads=$HALF_ALLOTED_CPUS torture.disable_onoff_at_boot csdlock_debug=1"
        torture_set "scftorture" tools/testing/selftests/rcutorture/bin/kvm.sh --torture scf --allcpus --duration "$duration_scftorture" --configs "$configs_scftorture" --kconfig "CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --memory ${scfmem}G --trust-make
 fi
@@ -559,7 +559,7 @@ do_kcsan="$do_kcsan_save"
 if test "$do_kvfree" = "yes"
 then
        torture_bootargs="rcuscale.kfree_rcu_test=1 rcuscale.kfree_nthreads=16 rcuscale.holdoff=20 rcuscale.kfree_loops=10000 torture.disable_onoff_at_boot"
-       torture_set "rcuscale-kvfree" tools/testing/selftests/rcutorture/bin/kvm.sh --torture rcuscale --allcpus --duration 10 --kconfig "CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --memory 2G --trust-make
+       torture_set "rcuscale-kvfree" tools/testing/selftests/rcutorture/bin/kvm.sh --torture rcuscale --allcpus --duration $duration_rcutorture --kconfig "CONFIG_NR_CPUS=$HALF_ALLOTED_CPUS" --memory 2G --trust-make
 fi
 
 if test "$do_clocksourcewd" = "yes"
index fc45645bb5f421c1c0ca122fa66af430e5d5c8e5..9ecd1b4e653d3f12547a18f452d9f3913ff19c91 100644 (file)
@@ -10,8 +10,9 @@ CONFIG_NO_HZ_FULL=n
 CONFIG_RCU_TRACE=n
 CONFIG_RCU_NOCB_CPU=n
 CONFIG_DEBUG_LOCK_ALLOC=n
-CONFIG_RCU_BOOST=n
+CONFIG_RCU_BOOST=y
+CONFIG_RCU_BOOST_DELAY=100
 CONFIG_DEBUG_OBJECTS_RCU_HEAD=n
-#CHECK#CONFIG_RCU_EXPERT=n
+CONFIG_RCU_EXPERT=y
 CONFIG_KPROBES=n
 CONFIG_FTRACE=n
index c537d52fafc586d5644ca6f7ec13a4358b4051c0..a40541bb7c7dee55baf1ec3e40c0727907a1c98d 100644 (file)
@@ -19,7 +19,7 @@
 #include "hwprobe.h"
 #include "../../kselftest.h"
 
-#define MK_CBO(fn) cpu_to_le32((fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
+#define MK_CBO(fn) le32_bswap((uint32_t)(fn) << 20 | 10 << 15 | 2 << 12 | 0 << 7 | 15)
 
 static char mem[4096] __aligned(4096) = { [0 ... 4095] = 0xa5 };
 
index e3fccb390c4dc94d0c224223192f767606b4da17..f3de970c32227bcfc6c9ce8608ba497724326b1c 100644 (file)
@@ -4,6 +4,16 @@
 #include <stddef.h>
 #include <asm/hwprobe.h>
 
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define le32_bswap(_x)                                \
+       ((((_x) & 0x000000ffU) << 24) |         \
+        (((_x) & 0x0000ff00U) <<  8) |         \
+        (((_x) & 0x00ff0000U) >>  8) |         \
+        (((_x) & 0xff000000U) >> 24))
+#else
+# define le32_bswap(_x) (_x)
+#endif
+
 /*
  * Rather than relying on having a new enough libc to define this, just do it
  * ourselves.  This way we don't need to be coupled to a new-enough libc to
index b5d592d4099e85c6ad9d19d36de055eb27415409..d975a67673299fe7fd617c4568e1c3afca93a96e 100644 (file)
@@ -158,6 +158,20 @@ static void handle_sigsys(int sig, siginfo_t *info, void *ucontext)
 
        /* In preparation for sigreturn. */
        SYSCALL_DISPATCH_OFF(glob_sel);
+
+       /*
+        * The tests for argument handling assume that `syscall(x) == x`. This
+        * is a NOP on x86 because the syscall number is passed in %rax, which
+        * happens to also be the function ABI return register.  Other
+        * architectures may need to swizzle the arguments around.
+        */
+#if defined(__riscv)
+/* REG_A7 is not defined in libc headers */
+# define REG_A7 (REG_A0 + 7)
+
+       ((ucontext_t *)ucontext)->uc_mcontext.__gregs[REG_A0] =
+                       ((ucontext_t *)ucontext)->uc_mcontext.__gregs[REG_A7];
+#endif
 }
 
 TEST(dispatch_and_return)
index cdfed403ba13f8da481fba1899aeb236c21585eb..7b543e7f04d7b0b7493d537d46f5d226612b7914 100644 (file)
 #if __riscv_xlen == 32
 #define VDSO_32BIT             1
 #endif
+#elif defined(__loongarch__)
+#define VDSO_VERSION           6
+#define VDSO_NAMES             1
 #endif
 
-static const char *versions[6] = {
+static const char *versions[7] = {
        "LINUX_2.6",
        "LINUX_2.6.15",
        "LINUX_2.6.29",
        "LINUX_2.6.39",
        "LINUX_4",
        "LINUX_4.15",
+       "LINUX_5.10"
 };
 
 static const char *names[2][6] = {
index 1df5d057d79f1d204e97eb26864e9203bc0b3d31..b758f68c6c9c2d91f1525ef3787abc29ee2df284 100644 (file)
 
 #include "../kselftest.h"
 #include "parse_vdso.h"
-
-#if defined(__riscv)
-const char *version = "LINUX_4.15";
-#else
-const char *version = "LINUX_2.6";
-#endif
-const char *name = "__vdso_getcpu";
+#include "vdso_config.h"
 
 struct getcpu_cache;
 typedef long (*getcpu_t)(unsigned int *, unsigned int *,
@@ -27,6 +21,8 @@ typedef long (*getcpu_t)(unsigned int *, unsigned int *,
 
 int main(int argc, char **argv)
 {
+       const char *version = versions[VDSO_VERSION];
+       const char **name = (const char **)&names[VDSO_NAMES];
        unsigned long sysinfo_ehdr;
        unsigned int cpu, node;
        getcpu_t get_cpu;
@@ -40,9 +36,9 @@ int main(int argc, char **argv)
 
        vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
 
-       get_cpu = (getcpu_t)vdso_sym(version, name);
+       get_cpu = (getcpu_t)vdso_sym(version, name[4]);
        if (!get_cpu) {
-               printf("Could not find %s\n", name);
+               printf("Could not find %s\n", name[4]);
                return KSFT_SKIP;
        }
 
@@ -50,7 +46,7 @@ int main(int argc, char **argv)
        if (ret == 0) {
                printf("Running on CPU %u node %u\n", cpu, node);
        } else {
-               printf("%s failed\n", name);
+               printf("%s failed\n", name[4]);
                return KSFT_FAIL;
        }
 
index e411f287a426c55c22f33ee1e2f9b1ce486cddec..ee4f1ca56a71ac85c71c4bbb8a56035ef739e701 100644 (file)
 
 #include "../kselftest.h"
 #include "parse_vdso.h"
-
-/*
- * ARM64's vDSO exports its gettimeofday() implementation with a different
- * name and version from other architectures, so we need to handle it as
- * a special case.
- */
-#if defined(__aarch64__)
-const char *version = "LINUX_2.6.39";
-const char *name = "__kernel_gettimeofday";
-#elif defined(__riscv)
-const char *version = "LINUX_4.15";
-const char *name = "__vdso_gettimeofday";
-#else
-const char *version = "LINUX_2.6";
-const char *name = "__vdso_gettimeofday";
-#endif
+#include "vdso_config.h"
 
 int main(int argc, char **argv)
 {
+       const char *version = versions[VDSO_VERSION];
+       const char **name = (const char **)&names[VDSO_NAMES];
+
        unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
        if (!sysinfo_ehdr) {
                printf("AT_SYSINFO_EHDR is not present!\n");
@@ -47,10 +35,10 @@ int main(int argc, char **argv)
 
        /* Find gettimeofday. */
        typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
-       gtod_t gtod = (gtod_t)vdso_sym(version, name);
+       gtod_t gtod = (gtod_t)vdso_sym(version, name[0]);
 
        if (!gtod) {
-               printf("Could not find %s\n", name);
+               printf("Could not find %s\n", name[0]);
                return KSFT_SKIP;
        }
 
@@ -61,7 +49,7 @@ int main(int argc, char **argv)
                printf("The time is %lld.%06lld\n",
                       (long long)tv.tv_sec, (long long)tv.tv_usec);
        } else {
-               printf("%s failed\n", name);
+               printf("%s failed\n", name[0]);
                return KSFT_FAIL;
        }
 
index a7f8e8a95625930aa568bb04a79fe9b05770be76..66290cf289a917ce4f57c07ab6805e9d47101957 100644 (file)
@@ -2,7 +2,7 @@ CONFIG_NONPORTABLE=y
 CONFIG_ARCH_RV32I=y
 CONFIG_MMU=y
 CONFIG_FPU=y
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
 CONFIG_RISCV_ISA_FALLBACK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
index daeb3e5e09658526b24b122b63ed05fa9078d212..db1aa9f388b9deea7085e724f60edc5a227d5415 100644 (file)
@@ -1,7 +1,7 @@
 CONFIG_ARCH_RV64I=y
 CONFIG_MMU=y
 CONFIG_FPU=y
-CONFIG_SOC_VIRT=y
+CONFIG_ARCH_VIRT=y
 CONFIG_RISCV_ISA_FALLBACK=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y